diff --git a/Dockerfile b/Dockerfile index b35191d..062cdeb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,14 @@ -FROM python:3.10-slim +FROM python:3.11-slim COPY Pipfile* /app/ WORKDIR /app/ RUN apt update && \ -apt install -y jq gcc libpq5 libpq-dev && \ -jq -r '.default | to_entries[] | .key + .value.version' Pipfile.lock > requirements.txt && \ -sed -i "s/psycopg2-binary/psycopg2/g" requirements.txt + apt install -y jq gcc libpq5 libpq-dev libmagic1 && \ + jq -r '.default | to_entries[] | .key + .value.version' Pipfile.lock > requirements.txt && \ + sed -i "s/psycopg2-binary/psycopg2/g" requirements.txt -RUN pip install -r requirements.txt +RUN pip install -r requirements.txt && \ + apt remove -y jq gcc COPY classquiz/ /app/classquiz/ COPY image_cleanup.py /app/image_cleanup.py diff --git a/Pipfile b/Pipfile index ab1bba2..f010ccd 100644 --- a/Pipfile +++ b/Pipfile @@ -30,13 +30,15 @@ pillow = ">=9.1.1" authlib = "*" httpx = "*" itsdangerous = "*" -puremagic = "*" py-avataaars-no-png = "*" cryptography = "*" -scheduler = "*" webauthn = "*" pyotp = "*" minio = "*" +xxhash = "*" +arq = "*" +thumbhash-python = "==1.0.0" +python-magic = "*" [dev-packages] coverage = "*" @@ -50,9 +52,10 @@ pre-commit = "*" python-socketio = {extras = ["client"], version = "*"} [requires] -python_version = "3.10" +python_version = "3.11" [scripts] format = "black ." lint = "flake8 classquiz" test = "coverage run -m pytest --lf -v --asyncio-mode=strict classquiz/tests" +worker = "arq classquiz.worker.WorkerSettings" diff --git a/Pipfile.lock b/Pipfile.lock index 1afaefa..ada2f3d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "0f27e59c80a47f8948353baf55cc7495131b532f2718bcd2ba08f25a40dc3dab" + "sha256": "f10247b4d32925c62f8f9c99a6b3d3bf0073f630d09cf15a7df884f86b78b0a2" }, "pipfile-spec": 6, "requires": { - "python_version": "3.10" + "python_version": "3.11" }, "sources": [ { @@ -127,11 +127,11 @@ }, "alembic": { "hashes": [ - "sha256:32a69b13a613aeb7e8093f242da60eff9daed13c0df02fff279c1b06c32965d2", - "sha256:b2e0a6cfd3a8ce936a1168320bcbe94aefa3f4463cd773a968a55071beb3cd37" + "sha256:6a810a6b012c88b33458fceb869aef09ac75d6ace5291915ba7fae44de372c01", + "sha256:dc871798a601fab38332e38d6ddb38d5e734f60034baeb8e2db5b642fccd8ab8" ], "index": "pypi", - "version": "==1.10.3" + "version": "==1.11.1" }, "anyio": { "hashes": [ @@ -176,6 +176,14 @@ "markers": "python_version >= '3.6'", "version": "==21.2.0" }, + "arq": { + "hashes": [ + "sha256:d176ebadfba920c039dc578814d19b7814d67fa15f82fdccccaedb4330d65dae", + "sha256:db072d0f39c0bc06b436db67ae1f315c81abc1527563b828955670531815290b" + ], + "index": "pypi", + "version": "==0.25.0" + }, "asn1crypto": { "hashes": [ "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c", @@ -188,7 +196,7 @@ "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" ], - "markers": "python_full_version <= '3.11.2'", + "markers": "python_version >= '3.6'", "version": "==4.0.2" }, "asyncpg": { @@ -472,7 +480,7 @@ "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.1.0" }, "click": { @@ -483,30 +491,44 @@ "markers": "python_version >= '3.7'", "version": "==8.1.3" }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "version": "==0.4.6" + }, + "commonmark": { + "hashes": [ + "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60", + "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9" + ], + "version": "==0.9.1" + }, "cryptography": { "hashes": [ - "sha256:0ddaee209d1cf1f180f1efa338a68c4621154de0afaef92b89486f5f96047c55", - "sha256:14754bcdae909d66ff24b7b5f166d69340ccc6cb15731670435efd5719294895", - "sha256:344c6de9f8bda3c425b3a41b319522ba3208551b70c2ae00099c205f0d9fd3be", - "sha256:34d405ea69a8b34566ba3dfb0521379b210ea5d560fafedf9f800a9a94a41928", - "sha256:3680248309d340fda9611498a5319b0193a8dbdb73586a1acf8109d06f25b92d", - "sha256:3c5ef25d060c80d6d9f7f9892e1d41bb1c79b78ce74805b8cb4aa373cb7d5ec8", - "sha256:4ab14d567f7bbe7f1cdff1c53d5324ed4d3fc8bd17c481b395db224fb405c237", - "sha256:5c1f7293c31ebc72163a9a0df246f890d65f66b4a40d9ec80081969ba8c78cc9", - "sha256:6b71f64beeea341c9b4f963b48ee3b62d62d57ba93eb120e1196b31dc1025e78", - "sha256:7d92f0248d38faa411d17f4107fc0bce0c42cae0b0ba5415505df72d751bf62d", - "sha256:8362565b3835ceacf4dc8f3b56471a2289cf51ac80946f9087e66dc283a810e0", - "sha256:84a165379cb9d411d58ed739e4af3396e544eac190805a54ba2e0322feb55c46", - "sha256:88ff107f211ea696455ea8d911389f6d2b276aabf3231bf72c8853d22db755c5", - "sha256:9f65e842cb02550fac96536edb1d17f24c0a338fd84eaf582be25926e993dde4", - "sha256:a4fc68d1c5b951cfb72dfd54702afdbbf0fb7acdc9b7dc4301bbf2225a27714d", - "sha256:b7f2f5c525a642cecad24ee8670443ba27ac1fab81bba4cc24c7b6b41f2d0c75", - "sha256:b846d59a8d5a9ba87e2c3d757ca019fa576793e8758174d3868aecb88d6fc8eb", - "sha256:bf8fc66012ca857d62f6a347007e166ed59c0bc150cefa49f28376ebe7d992a2", - "sha256:f5d0bf9b252f30a31664b6f64432b4730bb7038339bd18b1fafe129cfc2be9be" + "sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db", + "sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a", + "sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039", + "sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c", + "sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3", + "sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485", + "sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c", + "sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca", + "sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5", + "sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5", + "sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3", + "sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb", + "sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43", + "sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31", + "sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc", + "sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b", + "sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006", + "sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a", + "sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699" ], "index": "pypi", - "version": "==41.0.0" + "version": "==41.0.1" }, "databases": { "hashes": [ @@ -534,27 +556,19 @@ }, "email-validator": { "hashes": [ - "sha256:07c61b62ee446e39274b18204afa8e422baf64570776045272b04d10c02f64f6", - "sha256:f4904f4145c11f8de5897afbb8d7db4b465c57f13db1c8c106c16d02bceebd9a" + "sha256:1ff6e86044200c56ae23595695c54e9614f4a9551e0e393614f764860b3d7900", + "sha256:2466ba57cda361fb7309fd3d5a225723c788ca4bbad32a0ebd5373b99730285c" ], "index": "pypi", - "version": "==2.0.0" - }, - "exceptiongroup": { - "hashes": [ - "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e", - "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785" - ], - "markers": "python_version < '3.11'", - "version": "==1.1.1" + "version": "==2.0.0.post2" }, "fastapi": { "hashes": [ - "sha256:9569f0a381f8a457ec479d90fa01005cfddaae07546eb1f3fa035bc4797ae7d5", - "sha256:a870d443e5405982e1667dfe372663abf10754f246866056336d7f01c21dab07" + "sha256:95d757511c596409930bd20673358d4a4d709004edb85c5d24d6ffc48fabcbf2", + "sha256:b53248ee45f64f19bb7600953696e3edf94b0f7de94df1e5433fc5c6136fa986" ], "index": "pypi", - "version": "==0.95.1" + "version": "==0.97.0" }, "frozenlist": { "hashes": [ @@ -718,6 +732,100 @@ "markers": "python_version >= '3.7'", "version": "==0.14.0" }, + "hiredis": { + "hashes": [ + "sha256:071c5814b850574036506a8118034f97c3cbf2fe9947ff45a27b07a48da56240", + "sha256:08415ea74c1c29b9d6a4ca3dd0e810dc1af343c1d1d442e15ba133b11ab5be6a", + "sha256:126623b03c31cb6ac3e0d138feb6fcc36dd43dd34fc7da7b7a0c38b5d75bc896", + "sha256:14824e457e4f5cda685c3345d125da13949bcf3bb1c88eb5d248c8d2c3dee08f", + "sha256:15c2a551f3b8a26f7940d6ee10b837810201754b8d7e6f6b1391655370882c5a", + "sha256:17e938d9d3ee92e1adbff361706f1c36cc60eeb3e3eeca7a3a353eae344f4c91", + "sha256:1cadb0ac7ba3babfd804e425946bec9717b320564a1390f163a54af9365a720a", + "sha256:1d274d5c511dfc03f83f997d3238eaa9b6ee3f982640979f509373cced891e98", + "sha256:20f509e3a1a20d6e5f5794fc37ceb21f70f409101fcfe7a8bde783894d51b369", + "sha256:227c5b4bcb60f89008c275d596e4a7b6625a6b3c827b8a66ae582eace7051f71", + "sha256:232d0a70519865741ba56e1dfefd160a580ae78c30a1517bad47b3cf95a3bc7d", + "sha256:2443659c76b226267e2a04dbbb21bc2a3f91aa53bdc0c22964632753ae43a247", + "sha256:2d7e459fe7313925f395148d36d9b7f4f8dac65be06e45d7af356b187cef65fc", + "sha256:2fb9300959a0048138791f3d68359d61a788574ec9556bddf1fec07f2dbc5320", + "sha256:334f2738700b20faa04a0d813366fb16ed17287430a6b50584161d5ad31ca6d7", + "sha256:33a94d264e6e12a79d9bb8af333b01dc286b9f39c99072ab5fef94ce1f018e17", + "sha256:33bc4721632ef9708fa44e5df0066053fccc8e65410a2c48573192517a533b48", + "sha256:33ee3ea5cad3a8cb339352cd230b411eb437a2e75d7736c4899acab32056ccdb", + "sha256:3753df5f873d473f055e1f8837bfad0bd3b277c86f3c9bf058c58f14204cd901", + "sha256:3759f4789ae1913b7df278dfc9e8749205b7a106f888cd2903d19461e24a7697", + "sha256:3b7fe075e91b9d9cff40eba4fb6a8eff74964d3979a39be9a9ef58b1b4cb3604", + "sha256:3bf4b5bae472630c229518e4a814b1b68f10a3d9b00aeaec45f1a330f03a0251", + "sha256:3f006c28c885deb99b670a5a66f367a175ab8955b0374029bad7111f5357dcd4", + "sha256:3f5446068197b35a11ccc697720c41879c8657e2e761aaa8311783aac84cef20", + "sha256:3fa6811a618653164f918b891a0fa07052bd71a799defa5c44d167cac5557b26", + "sha256:46525fbd84523cac75af5bf524bc74aaac848beaf31b142d2df8a787d9b4bbc4", + "sha256:477c34c4489666dc73cb5e89dafe2617c3e13da1298917f73d55aac4696bd793", + "sha256:4b3e974ad15eb32b1f537730dea70b93a4c3db7b026de3ad2b59da49c6f7454d", + "sha256:4c3b8be557e08b234774925622e196f0ee36fe4eab66cd19df934d3efd8f3743", + "sha256:4e3e3e31423f888d396b1fc1f936936e52af868ac1ec17dd15e3eeba9dd4de24", + "sha256:4e43e2b5acaad09cf48c032f7e4926392bb3a3f01854416cf6d82ebff94d5467", + "sha256:4ed68a3b1ccb4313d2a42546fd7e7439ad4745918a48b6c9bcaa61e1e3e42634", + "sha256:4f674e309cd055ee7a48304ceb8cf43265d859faf4d7d01d270ce45e976ae9d3", + "sha256:50171f985e17970f87d5a29e16603d1e5b03bdbf5c2691a37e6c912942a6b657", + "sha256:51341e70b467004dcbec3a6ce8c478d2d6241e0f6b01e4c56764afd5022e1e9d", + "sha256:5a4bcef114fc071d5f52c386c47f35aae0a5b43673197b9288a15b584da8fa3a", + "sha256:5a5c8019ff94988d56eb49b15de76fe83f6b42536d76edeb6565dbf7fe14b973", + "sha256:5cda592405bbd29d53942e0389dc3fa77b49c362640210d7e94a10c14a677d4d", + "sha256:5e6674a017629284ef373b50496d9fb1a89b85a20a7fa100ecd109484ec748e5", + "sha256:5e7bb4dd524f50b71c20ef5a12bd61da9b463f8894b18a06130942fe31509881", + "sha256:60c4e3c258eafaab21b174b17270a0cc093718d61cdbde8c03f85ec4bf835343", + "sha256:61995eb826009d99ed8590747bc0da683a5f4fbb4faa8788166bf3810845cd5c", + "sha256:61a72e4a523cdfc521762137559c08dfa360a3caef63620be58c699d1717dac1", + "sha256:69536b821dd1bc78058a6e7541743f8d82bf2d981b91280b14c4daa6cdc7faba", + "sha256:6ccdcb635dae85b006592f78e32d97f4bc7541cb27829d505f9c7fefcef48298", + "sha256:6f88cafe46612b6fa68e6dea49e25bebf160598bba00101caa51cc8c1f18d597", + "sha256:6f969edc851efe23010e0f53a64269f2629a9364135e9ec81c842e8b2277d0c1", + "sha256:77924b0d32fd1f493d3df15d9609ddf9d94c31a364022a6bf6b525ce9da75bea", + "sha256:7df645b6b7800e8b748c217fbd6a4ca8361bcb9a1ae6206cc02377833ec8a1aa", + "sha256:7e17d04ea58ab8cf3f2dc52e875db16077c6357846006780086fff3189fb199d", + "sha256:7f2b34a6444b8f9c1e9f84bd2c639388e5d14f128afd14a869dfb3d9af893aa2", + "sha256:818dfd310aa1020a13cd08ee48e116dd8c3bb2e23b8161f8ac4df587dd5093d7", + "sha256:89a258424158eb8b3ed9f65548d68998da334ef155d09488c5637723eb1cd697", + "sha256:8eceffca3941775b646cd585cd19b275d382de43cc3327d22f7c75d7b003d481", + "sha256:8f280ab4e043b089777b43b4227bdc2035f88da5072ab36588e0ccf77d45d058", + "sha256:8f9dbe12f011a9b784f58faecc171d22465bb532c310bd588d769ba79a59ef5a", + "sha256:9076ce8429785c85f824650735791738de7143f61f43ae9ed83e163c0ca0fa44", + "sha256:95d2305fd2a7b179cacb48b10f618872fc565c175f9f62b854e8d1acac3e8a9e", + "sha256:96d9ea6c8d4cbdeee2e0d43379ce2881e4af0454b00570677c59f33f2531cd38", + "sha256:9944a2cac25ffe049a7e89f306e11b900640837d1ef38d9be0eaa4a4e2b73a52", + "sha256:9a1a80a8fa767f2fdc3870316a54b84fe9fc09fa6ab6a2686783de6a228a4604", + "sha256:9cd32326dfa6ce87edf754153b0105aca64486bebe93b9600ccff74fa0b224df", + "sha256:9f4a65276f6ecdebe75f2a53f578fbc40e8d2860658420d5e0611c56bbf5054c", + "sha256:a286ded34eb16501002e3713b3130c987366eee2ba0d58c33c72f27778e31676", + "sha256:a2df98f5e071320c7d84e8bd07c0542acdd0a7519307fc31774d60e4b842ec4f", + "sha256:a7205497d7276a81fe92951a29616ef96562ed2f91a02066f72b6f93cb34b40e", + "sha256:aa17a3b22b3726d54d7af20394f65d4a1735a842a4e0f557dc67a90f6965c4bc", + "sha256:af33f370be90b48bbaf0dab32decbdcc522b1fa95d109020a963282086518a8e", + "sha256:b17baf702c6e5b4bb66e1281a3efbb1d749c9d06cdb92b665ad81e03118f78fc", + "sha256:b4f3d06dc16671b88a13ae85d8ca92534c0b637d59e49f0558d040a691246422", + "sha256:b9953d87418ac228f508d93898ab572775e4d3b0eeb886a1a7734553bcdaf291", + "sha256:b9a7c987e161e3c58f992c63b7e26fea7fe0777f3b975799d23d65bbb8cb5899", + "sha256:c6cb613148422c523945cdb8b6bed617856f2602fd8750e33773ede2616e55d5", + "sha256:c9b9e5bde7030cae83aa900b5bd660decc65afd2db8c400f3c568c815a47ca2a", + "sha256:cc36a9dded458d4e37492fe3e619c6c83caae794d26ad925adbce61d592f8428", + "sha256:cd2614f17e261f72efc2f19f5e5ff2ee19e2296570c0dcf33409e22be30710de", + "sha256:d115790f18daa99b5c11a506e48923b630ef712e9e4b40482af942c3d40638b8", + "sha256:d194decd9608f11c777946f596f31d5aacad13972a0a87829ae1e6f2d26c1885", + "sha256:d1a4ce40ba11da9382c14da31f4f9e88c18f7d294f523decd0fadfb81f51ad18", + "sha256:d1be9e30e675f5bc1cb534633324578f6f0944a1bcffe53242cf632f554f83b6", + "sha256:d20891e3f33803b26d54c77fd5745878497091e33f4bbbdd454cf6e71aee8890", + "sha256:d27e560eefb57914d742a837f1da98d3b29cb22eff013c8023b7cf52ae6e051d", + "sha256:dcb0569dd5bfe6004658cd0f229efa699a3169dcb4f77bd72e188adda302063d", + "sha256:e62ec131816c6120eff40dffe43424e140264a15fa4ab88c301bd6a595913af3", + "sha256:e75163773a309e56a9b58165cf5a50e0f84b755f6ff863b2c01a38918fe92daa", + "sha256:ec58fb7c2062f835595c12f0f02dcda76d0eb0831423cc191d1e18c9276648de", + "sha256:f1eadbcd3de55ac42310ff82550d3302cb4efcd4e17d76646a17b6e7004bb42b", + "sha256:f2dcb8389fa3d453927b1299f46bdb38473c293c8269d5c777d33ea0e526b610", + "sha256:ffaf841546905d90ff189de7397aa56413b1ce5e54547f17a98f0ebf3a3b0a3b" + ], + "version": "==2.2.3" + }, "httpcore": { "hashes": [ "sha256:125f8375ab60036db632f34f4b627a9ad085048eef7cb7d2616fea0f739f98af", @@ -774,11 +882,11 @@ }, "httpx": { "hashes": [ - "sha256:447556b50c1921c351ea54b4fe79d91b724ed2b027462ab9a329465d147d5a4e", - "sha256:507d676fc3e26110d41df7d35ebd8b3b8585052450f4097401c9be59d928c63e" + "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd", + "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd" ], "index": "pypi", - "version": "==0.24.0" + "version": "==0.24.1" }, "idna": { "hashes": [ @@ -814,75 +922,75 @@ }, "markupsafe": { "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" + "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", + "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", + "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", + "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", + "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", + "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", + "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", + "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", + "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", + "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", + "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", + "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", + "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", + "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", + "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", + "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", + "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", + "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", + "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", + "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", + "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", + "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", + "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", + "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", + "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", + "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", + "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", + "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", + "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", + "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", + "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", + "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", + "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", + "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", + "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", + "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", + "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", + "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", + "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", + "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", + "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", + "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", + "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", + "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", + "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", + "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", + "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", + "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", + "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", + "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.1.3" }, "meilisearch": { "hashes": [ - "sha256:597ec5eaf6b726428c0e04ecf05af19379aa097093225dab0c6bfb892d03a90d", - "sha256:e35ad840a42554b575ddb72c6aa5d9f7202ab2a6777fada5752269fe453379f4" + "sha256:db084bc4e90608e3aa20d318de1cafc06db5dbd2e1561003634fa05e5025bc5e", + "sha256:ff3ab30c92a8b1ae8ddbab9f7b94a0830ccbf6bf84f209664e2b1de076541e76" ], "index": "pypi", - "version": "==0.26.0" + "version": "==0.28.0" }, "minio": { "hashes": [ - "sha256:230faf1d0db1c3ce09aef86b0eb38e994a64769e34dad4b77febf59bc90d8ab0", - "sha256:ee5cbd4ba73f71b73555209f3411d5da3e9742bbe3fd038c362042d6d2527256" + "sha256:1afdf01c1bc8b57ddd12d438e3e168d625465b56f4d1c2af7576744c688e84c6", + "sha256:fcf8ac2cef310d5ddff2bef2c42f4e5a8bb546b87bca5bf8832135db054ca4e1" ], "index": "pypi", - "version": "==7.1.14" + "version": "==7.1.15" }, "multidict": { "hashes": [ @@ -1122,14 +1230,6 @@ ], "version": "==2.9.6" }, - "puremagic": { - "hashes": [ - "sha256:349e179f04bcc14eb0e2c3941cd9ee4ea74881ab6ccac63ea0c37c98f7a80b22", - "sha256:6e46aa78113a466abc9f69e6e8a4ce90eb57d908dafb809597012621061462bd" - ], - "index": "pypi", - "version": "==1.15" - }, "py-avataaars-no-png": { "hashes": [ "sha256:9cd593fe93d6e223626903da7310ad53e857b3fd856ce7e7f2b1faa401740054", @@ -1195,6 +1295,14 @@ "index": "pypi", "version": "==1.10.4" }, + "pygments": { + "hashes": [ + "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c", + "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.15.1" + }, "pyopenssl": { "hashes": [ "sha256:24f0dc5227396b3e831f4c7f602b950a5e9833d292c8e4a2e06b709292806ae2", @@ -1241,6 +1349,14 @@ "index": "pypi", "version": "==3.3.0" }, + "python-magic": { + "hashes": [ + "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b", + "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3" + ], + "index": "pypi", + "version": "==0.4.27" + }, "python-multipart": { "hashes": [ "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132", @@ -1312,11 +1428,11 @@ }, "redis": { "hashes": [ - "sha256:2c19e6767c474f2e85167909061d525ed65bea9301c0770bb151e041b7ac89a2", - "sha256:73ec35da4da267d6847e47f68730fdd5f62e2ca69e3ef5885c6a78a9374c3893" + "sha256:77929bc7f5dab9adf3acba2d3bb7d7658f1e0c2f1cafe7eb36434e751c471119", + "sha256:dc87a0bdef6c8bfe1ef1e1c40be7034390c2ae02d92dcd0c7ca1729443899880" ], "index": "pypi", - "version": "==4.5.4" + "version": "==4.5.5" }, "requests": { "hashes": [ @@ -1326,29 +1442,28 @@ "markers": "python_version >= '3.7'", "version": "==2.31.0" }, + "rich": { + "hashes": [ + "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e", + "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0" + ], + "version": "==12.6.0" + }, "rsa": { "hashes": [ "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" ], - "markers": "python_version >= '3.6' and python_version < '4.0'", + "markers": "python_version >= '3.6' and python_version < '4'", "version": "==4.9" }, - "scheduler": { - "hashes": [ - "sha256:48e8fe16f4a0cbd24f169a2ed4f65b99fb0c3a7f4a28f4dfbf26cc901ab4112b", - "sha256:5ae5181d8462d89307bdae588b47f290a2fb7e3fa1073650354e01eb87a265f4" - ], - "index": "pypi", - "version": "==0.8.4" - }, "sentry-sdk": { "hashes": [ - "sha256:7ae78bd921981a5010ab540d6bdf3b793659a4db8cccf7f16180702d48a80d84", - "sha256:885a11c69df23e53eb281d003b9ff15a5bdfa43d8a2a53589be52104a1b4582f" + "sha256:79afb7c896014038e358401ad1d36889f97a129dfa8031c49b3f238cd1aa3935", + "sha256:aa796423eb6a2f4a8cd7a5b02ba6558cb10aab4ccdc0537f63a47b038c520c38" ], "index": "pypi", - "version": "==1.19.1" + "version": "==1.25.1" }, "setuptools": { "hashes": [ @@ -1358,6 +1473,13 @@ "markers": "python_version >= '3.7'", "version": "==67.8.0" }, + "shellingham": { + "hashes": [ + "sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744", + "sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28" + ], + "version": "==1.5.0.post1" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -1423,19 +1545,30 @@ }, "starlette": { "hashes": [ - "sha256:41da799057ea8620e4667a3e69a5b1923ebd32b1819c8fa75634bbe8d8bea9bd", - "sha256:e87fce5d7cbdde34b76f0ac69013fd9d190d581d80681493016666e6f96c6d5e" + "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75", + "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91" ], "markers": "python_version >= '3.7'", - "version": "==0.26.1" + "version": "==0.27.0" }, - "typeguard": { + "thumbhash-python": { "hashes": [ - "sha256:194fb3dbcb06ea9caf7088f3befee014de57961689f9c859ac5239b1ef61d987", - "sha256:c4a40af0ba8a41077221271b46d0a6d8d46045443e4d887887c69254ca861952" + "sha256:17ad1f8cb8fb4dd3c0738cc2c60e8c5ef18c345290b7ff5f22fa16973c7b356c", + "sha256:755379a45c994cc0bcb06a7cac41880fb7966d65373560b1631e96ad2a59c6a6" ], - "markers": "python_full_version >= '3.7.4'", - "version": "==4.0.0" + "index": "pypi", + "version": "==1.0.0" + }, + "typer": { + "extras": [ + "all" + ], + "hashes": [ + "sha256:b5e704f4e48ec263de1c0b3a2387cd405a13767d2f907f44c1a08cbad96f606d", + "sha256:ff797846578a9f2a201b53442aedeb543319466870fbe1c701eab66dd7681165" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" }, "typing-extensions": { "hashes": [ @@ -1447,22 +1580,22 @@ }, "urllib3": { "hashes": [ - "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc", - "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e" + "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", + "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" ], "markers": "python_version >= '3.7'", - "version": "==2.0.2" + "version": "==2.0.3" }, "uvicorn": { "extras": [ "standard" ], "hashes": [ - "sha256:0fac9cb342ba099e0d582966005f3fdba5b0290579fed4a6266dc702ca7bb032", - "sha256:e47cac98a6da10cd41e6fd036d472c6f58ede6c5dbee3dbee3ef7a100ed97742" + "sha256:79277ae03db57ce7d9aa0567830bbb51d7a612f54d6e1e3e92da3ef24c2c8ed8", + "sha256:e9434d3bbf05f310e762147f769c9f21235ee118ba2d2bf1155a7196448bd996" ], "index": "pypi", - "version": "==0.21.1" + "version": "==0.22.0" }, "uvloop": { "hashes": [ @@ -1528,11 +1661,11 @@ }, "webauthn": { "hashes": [ - "sha256:0c981eb2575d66fa0a6586c2bfb24d9812dff8e158009a9030bc867717727709", - "sha256:1b87d55acd86234475591e2f60163232ba98d91685f235803f258fc891ebb6c0" + "sha256:53914b8529df3e70bec0e41438eea8d99442ad3e54e32b86ce1ba83513bcf30e", + "sha256:caca3cc62045923c542819169c22122bdb81efa0246c9d5208d073942d806bf3" ], "index": "pypi", - "version": "==1.8.0" + "version": "==1.8.1" }, "webencodings": { "hashes": [ @@ -1618,11 +1751,115 @@ }, "xlsxwriter": { "hashes": [ - "sha256:02913b50b74c00f165933d5da3e3a02cab4204cb4932722a1b342c5c71034122", - "sha256:b70a147d36235d1ee835cfd037396f789db1f76740a0e5c917d54137169341de" + "sha256:331508ff39d610ecdaf979e458840bc1eab6e6a02cfd5d08f044f0f73636236f", + "sha256:78751099a770273f1c98b8d6643351f68f98ae8e6acf9d09d37dc6798f8cd3de" ], "index": "pypi", - "version": "==3.1.0" + "version": "==3.1.2" + }, + "xxhash": { + "hashes": [ + "sha256:01f36b671ff55cb1d5c2f6058b799b697fd0ae4b4582bba6ed0999678068172a", + "sha256:02badf3754e2133de254a4688798c4d80f0060635087abcb461415cb3eb82115", + "sha256:052fd0efdd5525c2dbc61bebb423d92aa619c4905bba605afbf1e985a562a231", + "sha256:0a2cdfb5cae9fafb9f7b65fd52ecd60cf7d72c13bb2591ea59aaefa03d5a8827", + "sha256:0a6d58ba5865475e53d6c2c4fa6a62e2721e7875e146e2681e5337a6948f12e7", + "sha256:0d54ac023eef7e3ac9f0b8841ae8a376b933043bc2ad428121346c6fa61c491c", + "sha256:0dcb419bf7b0bc77d366e5005c25682249c5521a63fd36c51f584bd91bb13bd5", + "sha256:0eea848758e4823a01abdbcccb021a03c1ee4100411cbeeb7a5c36a202a0c13c", + "sha256:11bf87dc7bb8c3b0b5e24b7b941a9a19d8c1f88120b6a03a17264086bc8bb023", + "sha256:17b65454c5accbb079c45eca546c27c4782f5175aa320758fafac896b1549d27", + "sha256:1a42994f0d42b55514785356722d9031f064fd34e495b3a589e96db68ee0179d", + "sha256:1afb9b9d27fd675b436cb110c15979976d92d761ad6e66799b83756402f3a974", + "sha256:1afd47af8955c5db730f630ad53ae798cf7fae0acb64cebb3cf94d35c47dd088", + "sha256:1bdd57973e2b802ef32553d7bebf9402dac1557874dbe5c908b499ea917662cd", + "sha256:20181cbaed033c72cb881b2a1d13c629cd1228f113046133469c9a48cfcbcd36", + "sha256:2198c4901a0223c48f6ec0a978b60bca4f4f7229a11ca4dc96ca325dd6a29115", + "sha256:2408d49260b0a4a7cc6ba445aebf38e073aeaf482f8e32767ca477e32ccbbf9e", + "sha256:26cb52174a7e96a17acad27a3ca65b24713610ac479c99ac9640843822d3bebf", + "sha256:2783d41487ce6d379fdfaa7332fca5187bf7010b9bddcf20cafba923bc1dc665", + "sha256:3126df6520cbdbaddd87ce74794b2b6c45dd2cf6ac2b600a374b8cdb76a2548c", + "sha256:314ec0bd21f0ee8d30f2bd82ed3759314bd317ddbbd8555668f3d20ab7a8899a", + "sha256:368265392cb696dd53907e2328b5a8c1bee81cf2142d0cc743caf1c1047abb36", + "sha256:3a26eeb4625a6e61cedc8c1b39b89327c9c7e1a8c2c4d786fe3f178eb839ede6", + "sha256:3a68d1e8a390b660d94b9360ae5baa8c21a101bd9c4790a8b30781bada9f1fc6", + "sha256:3b1f3c6d67fa9f49c4ff6b25ce0e7143bab88a5bc0f4116dd290c92337d0ecc7", + "sha256:3d4b15c00e807b1d3d0b612338c814739dec310b80fb069bd732b98ddc709ad7", + "sha256:3f4152fd0bf8b03b79f2f900fd6087a66866537e94b5a11fd0fd99ef7efe5c42", + "sha256:498843b66b9ca416e9d03037e5875c8d0c0ab9037527e22df3b39aa5163214cd", + "sha256:49f51fab7b762da7c2cee0a3d575184d3b9be5e2f64f26cae2dd286258ac9b3c", + "sha256:4b948a03f89f5c72d69d40975af8af241111f0643228796558dc1cae8f5560b0", + "sha256:4ec1f57127879b419a2c8d2db9d9978eb26c61ae17e5972197830430ae78d25b", + "sha256:50ce82a71b22a3069c02e914bf842118a53065e2ec1c6fb54786e03608ab89cc", + "sha256:5384f1d9f30876f5d5b618464fb19ff7ce6c0fe4c690fbaafd1c52adc3aae807", + "sha256:561076ca0dcef2fbc20b2bc2765bff099e002e96041ae9dbe910a863ca6ee3ea", + "sha256:59dc8bfacf89b8f5be54d55bc3b4bd6d74d0c5320c8a63d2538ac7df5b96f1d5", + "sha256:5daff3fb5bfef30bc5a2cb143810d376d43461445aa17aece7210de52adbe151", + "sha256:61b0bcf946fdfd8ab5f09179dc2b5c74d1ef47cedfc6ed0ec01fdf0ee8682dd3", + "sha256:61e6aa1d30c2af692aa88c4dd48709426e8b37bff6a574ee2de677579c34a3d6", + "sha256:649cdf19df175925ad87289ead6f760cd840730ee85abc5eb43be326a0a24d97", + "sha256:66b8a90b28c13c2aae7a71b32638ceb14cefc2a1c8cf23d8d50dfb64dfac7aaf", + "sha256:6b7c9aa77bbce61a5e681bd39cb6a804338474dcc90abe3c543592aa5d6c9a9b", + "sha256:75aa692936942ccb2e8fd6a386c81c61630ac1b6d6e921698122db8a930579c3", + "sha256:75bb5be3c5de702a547715f320ecf5c8014aeca750ed5147ca75389bd22e7343", + "sha256:761df3c7e2c5270088b691c5a8121004f84318177da1ca1db64222ec83c44871", + "sha256:77709139af5123c578ab06cf999429cdb9ab211047acd0c787e098dcb3f1cb4d", + "sha256:7deae3a312feb5c17c97cbf18129f83cbd3f1f9ec25b0f50e2bd9697befb22e7", + "sha256:82daaab720866bf690b20b49de5640b0c27e3b8eea2d08aa75bdca2b0f0cfb63", + "sha256:883dc3d3942620f4c7dbc3fd6162f50a67f050b714e47da77444e3bcea7d91cc", + "sha256:89585adc73395a10306d2e2036e50d6c4ac0cf8dd47edf914c25488871b64f6d", + "sha256:8970f6a411a9839a02b23b7e90bbbba4a6de52ace009274998566dc43f36ca18", + "sha256:91687671fd9d484a4e201ad266d366b695a45a1f2b41be93d116ba60f1b8f3b3", + "sha256:919bc1b010aa6ff0eb918838ff73a435aed9e9a19c3202b91acecd296bf75607", + "sha256:92fd765591c83e5c5f409b33eac1d3266c03d3d11c71a7dbade36d5cdee4fbc0", + "sha256:994e4741d5ed70fc2a335a91ef79343c6b1089d7dfe6e955dd06f8ffe82bede6", + "sha256:9b94749130ef3119375c599bfce82142c2500ef9ed3280089157ee37662a7137", + "sha256:9d3f686e3d1c8900c5459eee02b60c7399e20ec5c6402364068a343c83a61d90", + "sha256:9eba0c7c12126b12f7fcbea5513f28c950d28f33d2a227f74b50b77789e478e8", + "sha256:a0e1bd0260c1da35c1883321ce2707ceea07127816ab625e1226ec95177b561a", + "sha256:a0f7a16138279d707db778a63264d1d6016ac13ffd3f1e99f54b2855d6c0d8e1", + "sha256:a32d546a1752e4ee7805d6db57944f7224afa7428d22867006b6486e4195c1f3", + "sha256:a433f6162b18d52f7068175d00bd5b1563b7405f926a48d888a97b90a160c40d", + "sha256:a892b4b139126a86bfdcb97cd912a2f8c4e8623869c3ef7b50871451dd7afeb0", + "sha256:a910b1193cd90af17228f5d6069816646df0148f14f53eefa6b2b11a1dedfcd0", + "sha256:aabdbc082030f8df613e2d2ea1f974e7ad36a539bdfc40d36f34e55c7e4b8e94", + "sha256:add774341c09853b1612c64a526032d95ab1683053325403e1afbe3ad2f374c5", + "sha256:ae521ed9287f86aac979eeac43af762f03d9d9797b2272185fb9ddd810391216", + "sha256:af44b9e59c4b2926a4e3c7f9d29949ff42fcea28637ff6b8182e654461932be8", + "sha256:b0c094d5e65a46dbf3fe0928ff20873a747e6abfd2ed4b675beeb2750624bc2e", + "sha256:b0d16775094423088ffa357d09fbbb9ab48d2fb721d42c0856b801c86f616eec", + "sha256:b5019fb33711c30e54e4e57ae0ca70af9d35b589d385ac04acd6954452fa73bb", + "sha256:baa99cebf95c1885db21e119395f222a706a2bb75a545f0672880a442137725e", + "sha256:bb6d8ce31dc25faf4da92991320e211fa7f42de010ef51937b1dc565a4926501", + "sha256:bbc30c98ab006ab9fc47e5ed439c00f706bc9d4441ff52693b8b6fea335163e0", + "sha256:c55fa832fc3fe64e0d29da5dc9b50ba66ca93312107cec2709300ea3d3bab5c7", + "sha256:c5e8db6e1ee7267b7c412ad0afd5863bf7a95286b8333a5958c8097c69f94cf5", + "sha256:c5f3e33fe6cbab481727f9aeb136a213aed7e33cd1ca27bd75e916ffacc18411", + "sha256:cc8878935671490efe9275fb4190a6062b73277bd273237179b9b5a2aa436153", + "sha256:ce7c3ce28f94302df95eaea7c9c1e2c974b6d15d78a0c82142a97939d7b6c082", + "sha256:cead7c0307977a00b3f784cff676e72c147adbcada19a2e6fc2ddf54f37cf387", + "sha256:d2d15a707e7f689531eb4134eccb0f8bf3844bb8255ad50823aa39708d9e6755", + "sha256:d4d4519123aac73c93159eb8f61db9682393862dd669e7eae034ecd0a35eadac", + "sha256:d93a44d0104d1b9b10de4e7aadf747f6efc1d7ec5ed0aa3f233a720725dd31bd", + "sha256:dad638cde3a5357ad3163b80b3127df61fb5b5e34e9e05a87697144400ba03c7", + "sha256:e0773cd5c438ffcd5dbff91cdd503574f88a4b960e70cedeb67736583a17a918", + "sha256:e172c1ee40507ae3b8d220f4048aaca204f203e1e4197e8e652f5c814f61d1aa", + "sha256:e4af8bc5c3fcc2192c266421c6aa2daab1a18e002cb8e66ef672030e46ae25cf", + "sha256:e57d94a1552af67f67b27db5dba0b03783ea69d5ca2af2f40e098f0ba3ce3f5f", + "sha256:e6b2ba4ff53dd5f57d728095e3def7375eb19c90621ce3b41b256de84ec61cfd", + "sha256:e8be562e2ce3e481d9209b6f254c3d7c5ff920eb256aba2380d2fb5ba75d4f87", + "sha256:e8ed3bd2b8bb3277710843ca63e4f5c3ee6f8f80b083be5b19a7a9905420d11e", + "sha256:e998efb190653f70e0f30d92b39fc645145369a4823bee46af8ddfc244aa969d", + "sha256:eaa3ea15025b56076d806b248948612289b093e8dcda8d013776b3848dffff15", + "sha256:f4ce006215497993ae77c612c1883ca4f3973899573ce0c52fee91f0d39c4561", + "sha256:f7b79f0f302396d8e0d444826ceb3d07b61977793886ebae04e82796c02e42dc", + "sha256:f94163ebe2d5546e6a5977e96d83621f4689c1054053428cf8d4c28b10f92f69", + "sha256:f988daf25f31726d5b9d0be6af636ca9000898f9ea43a57eac594daea25b0948", + "sha256:fbcd613a5e76b1495fc24db9c37a6b7ee5f214fd85979187ec4e032abfc12ded", + "sha256:fe454aeab348c42f56d6f7434ff758a3ef90787ac81b9ad5a363cd61b90a1b0b" + ], + "index": "pypi", + "version": "==3.2.0" }, "yarl": { "hashes": [ @@ -1839,7 +2076,7 @@ "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.1.0" }, "click": { @@ -1852,60 +2089,69 @@ }, "coverage": { "hashes": [ - "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93", - "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013", - "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f", - "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21", - "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462", - "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc", - "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df", - "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1", - "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235", - "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934", - "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9", - "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1", - "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48", - "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4", - "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe", - "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a", - "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b", - "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21", - "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d", - "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa", - "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367", - "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535", - "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152", - "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e", - "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539", - "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1", - "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925", - "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0", - "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2", - "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab", - "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841", - "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30", - "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91", - "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c", - "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257", - "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9", - "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040", - "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911", - "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623", - "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259", - "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c", - "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79", - "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5", - "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4", - "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4", - "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22", - "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd", - "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1", - "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910", - "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859", - "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312" + "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f", + "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2", + "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a", + "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a", + "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01", + "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6", + "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7", + "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f", + "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02", + "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c", + "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063", + "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a", + "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5", + "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959", + "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97", + "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6", + "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f", + "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9", + "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5", + "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f", + "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562", + "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe", + "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9", + "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f", + "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb", + "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb", + "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1", + "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb", + "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250", + "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e", + "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511", + "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5", + "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59", + "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2", + "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d", + "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3", + "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4", + "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de", + "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9", + "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833", + "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0", + "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9", + "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d", + "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050", + "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d", + "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6", + "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353", + "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb", + "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e", + "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8", + "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495", + "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2", + "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd", + "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27", + "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1", + "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818", + "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4", + "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e", + "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850", + "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3" ], "index": "pypi", - "version": "==7.2.3" + "version": "==7.2.7" }, "distlib": { "hashes": [ @@ -1914,21 +2160,13 @@ ], "version": "==0.3.6" }, - "exceptiongroup": { - "hashes": [ - "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e", - "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785" - ], - "markers": "python_version < '3.11'", - "version": "==1.1.1" - }, "filelock": { "hashes": [ - "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9", - "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718" + "sha256:42f1e4ff2b497311213d61ad7aac5fed9050608e5309573f101eefa94143134a", + "sha256:82b1f7da46f0ae42abf1bc78e548667f484ac59d2bcec38c713cee7e2eb51e83" ], "markers": "python_version >= '3.7'", - "version": "==3.12.0" + "version": "==3.12.1" }, "flake8": { "hashes": [ @@ -2004,11 +2242,11 @@ }, "platformdirs": { "hashes": [ - "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f", - "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5" + "sha256:0ade98a4895e87dc51d47151f7d2ec290365a585151d97b4d8d6312ed6132fed", + "sha256:e48fabd87db8f3a7df7150a4a5ea22c546ee8bc39bc2473244730d4b56d2cc4e" ], "markers": "python_version >= '3.7'", - "version": "==3.5.1" + "version": "==3.5.3" }, "pluggy": { "hashes": [ @@ -2020,11 +2258,11 @@ }, "pre-commit": { "hashes": [ - "sha256:0b4210aea813fe81144e87c5a291f09ea66f199f367fa1df41b55e1d26e1e2b4", - "sha256:5b808fcbda4afbccf6d6633a56663fed35b6c2bc08096fd3d47ce197ac351d9d" + "sha256:66e37bec2d882de1f17f88075047ef8962581f83c234ac08da21a0c58953d1f0", + "sha256:8056bc52181efadf4aac792b1f4f255dfd2fb5a350ded7335d251a68561e8cb6" ], "index": "pypi", - "version": "==3.2.2" + "version": "==3.3.2" }, "pycodestyle": { "hashes": [ @@ -2044,11 +2282,11 @@ }, "pytest": { "hashes": [ - "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362", - "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3" + "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295", + "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b" ], "index": "pypi", - "version": "==7.3.1" + "version": "==7.3.2" }, "pytest-asyncio": { "hashes": [ @@ -2150,21 +2388,13 @@ "markers": "python_version >= '3.7'", "version": "==67.8.0" }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" - }, "urllib3": { "hashes": [ - "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc", - "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e" + "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", + "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" ], "markers": "python_version >= '3.7'", - "version": "==2.0.2" + "version": "==2.0.3" }, "virtualenv": { "hashes": [ @@ -2176,10 +2406,10 @@ }, "websocket-client": { "hashes": [ - "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b", - "sha256:f8c64e28cd700e7ba1f04350d66422b6833b82a796b525a51e740b8cc8dab4b1" + "sha256:3566f8467cd350874c4913816355642a4942f6c1ed1e9406e3d42fae6d6c072a", + "sha256:b96f3bce3e54e3486ebe6504bc22bd4c140392bd2eb71764db29be8f2639aa65" ], - "version": "==1.5.2" + "version": "==1.5.3" } } } diff --git a/classquiz/__init__.py b/classquiz/__init__.py index 735b7d0..978abea 100644 --- a/classquiz/__init__.py +++ b/classquiz/__init__.py @@ -1,7 +1,6 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -import asyncio import sentry_sdk from fastapi import FastAPI, Request @@ -11,7 +10,6 @@ from starlette.middleware.sessions import SessionMiddleware from classquiz.config import settings from classquiz.db import database -from datetime import timedelta from classquiz.oauth import rememberme_middleware from classquiz.routers import ( @@ -36,8 +34,7 @@ from classquiz.routers import ( quiztivity, ) from classquiz.socket_server import sio -from classquiz.helpers import meilisearch_init, telemetry_ping, bg_tasks -from scheduler.asyncio import Scheduler +from classquiz.helpers import meilisearch_init, telemetry_ping settings = settings() if settings.sentry_dsn: @@ -58,13 +55,6 @@ async def sentry_exception(request: Request, call_next): raise e -async def background_tasks(): - schedule = Scheduler() - schedule.cyclic(timedelta(hours=6), bg_tasks.clean_editor_images_up) - while True: - await asyncio.sleep(1) - - @app.on_event("startup") async def startup() -> None: database_ = app.state.database @@ -72,7 +62,6 @@ async def startup() -> None: await database_.connect() await meilisearch_init() await telemetry_ping() - asyncio.create_task(background_tasks()) @app.on_event("shutdown") diff --git a/classquiz/config.py b/classquiz/config.py index 354c391..49a8476 100644 --- a/classquiz/config.py +++ b/classquiz/config.py @@ -9,6 +9,8 @@ import redis as redis_base_lib from pydantic import BaseSettings, RedisDsn, PostgresDsn, BaseModel import meilisearch as MeiliSearch from typing import Optional +from arq import create_pool +from arq.connections import RedisSettings, ArqRedis from classquiz.storage import Storage @@ -48,12 +50,10 @@ class Settings(BaseSettings): github_client_secret: Optional[str] custom_openid_provider: CustomOpenIDProvider | None = None telemetry_enabled: bool = True + free_storage_limit: int = 1074000000 # storage_backend - storage_backend: str | None = "deta" - # if storage_backend == "deta": - deta_project_key: str | None - deta_project_id: str | None + storage_backend: str | None = "local" # if storage_backend == "local": storage_path: str | None @@ -70,16 +70,24 @@ class Settings(BaseSettings): env_nested_delimiter = "__" +async def initialize_arq(): + global arq + arq = await create_pool(RedisSettings.from_dsn(settings.redis)) + + @lru_cache() def settings() -> Settings: return Settings() -redis: redis_base_lib.client.Redis = redis_lib.Redis().from_url(settings().redis) +# asyncio.run(initialize_arq()) + +pool = redis_lib.ConnectionPool().from_url(settings().redis) + +redis: redis_base_lib.client.Redis = redis_lib.Redis(connection_pool=pool) +arq: ArqRedis = ArqRedis(pool_or_conn=pool) storage: Storage = Storage( backend=settings().storage_backend, - deta_key=settings().deta_project_key, - deta_id=settings().deta_project_id, storage_path=settings().storage_path, access_key=settings().s3_access_key, secret_key=settings().s3_secret_key, diff --git a/classquiz/db/models.py b/classquiz/db/models.py index 8f177c7..7d3ef0f 100644 --- a/classquiz/db/models.py +++ b/classquiz/db/models.py @@ -8,6 +8,7 @@ from datetime import datetime from typing import Optional import ormar +from ormar import ReferentialAction from pydantic import BaseModel, Json, validator from enum import Enum from . import metadata, database @@ -42,6 +43,7 @@ class User(ormar.Model): require_password: bool = ormar.Boolean(default=True, nullable=False) backup_code: str = ormar.String(max_length=64, min_length=64, nullable=False, default=os.urandom(32).hex()) totp_secret: str = ormar.String(max_length=32, min_length=32, nullable=True, default=None) + storage_used: int = ormar.BigInteger(nullable=False, default=0, minimum=0) class Meta: tablename = "users" @@ -57,7 +59,7 @@ class FidoCredentials(ormar.Model): id: bytes = ormar.LargeBinary(max_length=256) public_key: bytes = ormar.LargeBinary(max_length=256) sign_count: int = ormar.Integer() - user: Optional[User] = ormar.ForeignKey(User) + user: Optional[User] = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) class Meta: tablename = "fido_credentials" @@ -67,7 +69,7 @@ class FidoCredentials(ormar.Model): class ApiKey(ormar.Model): key: str = ormar.String(max_length=48, min_length=48, primary_key=True) - user: Optional[User] = ormar.ForeignKey(User) + user: Optional[User] = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) class Meta: tablename = "api_keys" @@ -81,7 +83,7 @@ class UserSession(ormar.Model): """ id: uuid.UUID = ormar.UUID(primary_key=True, default=uuid.uuid4()) - user: Optional[User] = ormar.ForeignKey(User) + user: Optional[User] = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) session_key: str = ormar.String(unique=True, max_length=64) created_at: datetime = ormar.DateTime(default=datetime.now()) ip_address: str = ormar.String(max_length=100, nullable=True) @@ -180,7 +182,7 @@ class Quiz(ormar.Model): description: str = ormar.Text(nullable=True) created_at: datetime = ormar.DateTime(default=datetime.now()) updated_at: datetime = ormar.DateTime(default=datetime.now()) - user_id: uuid.UUID = ormar.ForeignKey(User) + user_id: uuid.UUID = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) questions: Json[list[QuizQuestion]] = ormar.JSON(nullable=False) imported_from_kahoot: Optional[bool] = ormar.Boolean(default=False, nullable=True) cover_image: Optional[str] = ormar.Text(nullable=True, unique=False) @@ -306,8 +308,8 @@ class GameInLobby(BaseModel): class GameResults(ormar.Model): id: uuid.UUID = ormar.UUID(primary_key=True) - quiz: uuid.UUID | Quiz = ormar.ForeignKey(Quiz) - user: uuid.UUID | User = ormar.ForeignKey(User) + quiz: uuid.UUID | Quiz = ormar.ForeignKey(Quiz, ondelete=ReferentialAction.CASCADE) + user: uuid.UUID | User = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) timestamp: datetime = ormar.DateTime(default=datetime.now(), nullable=False) player_count: int = ormar.Integer(nullable=False, default=0) note: str | None = ormar.Text(nullable=True) @@ -333,7 +335,7 @@ class QuizTivity(ormar.Model): id: uuid.UUID = ormar.UUID(primary_key=True) title: str = ormar.Text(nullable=False) created_at: datetime = ormar.DateTime(nullable=False, server_default=func.now()) - user: User | None = ormar.ForeignKey(User) + user: User | None = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) pages: list[QuizTivityPage] = ormar.JSON(nullable=False) class Meta: @@ -346,8 +348,8 @@ class QuizTivityShare(ormar.Model): id: uuid.UUID = ormar.UUID(primary_key=True) name: str | None = ormar.Text(nullable=True) expire_at: datetime | None = ormar.DateTime(nullable=True) - quiztivity: QuizTivity | None = ormar.ForeignKey(QuizTivity) - user: User | None = ormar.ForeignKey(User) + quiztivity: QuizTivity | None = ormar.ForeignKey(QuizTivity, ondelete=ReferentialAction.CASCADE) + user: User | None = ormar.ForeignKey(User, ondelete=ReferentialAction.CASCADE) class Meta: tablename = "quiztivityshares" @@ -378,3 +380,96 @@ class PublicQuizTivityShare(BaseModel): quiztivity=OnlyId(id=data.quiztivity.id), user=OnlyId(id=data.user.id), ) + + +class StorageItem(ormar.Model): + id: uuid.UUID = ormar.UUID(primary_key=True) + uploaded_at: datetime = ormar.DateTime(nullable=False, default=datetime.now()) + mime_type: str = ormar.Text(nullable=False) + hash: bytes | None = ormar.LargeBinary(nullable=True, min_length=16, max_length=16) + user: User | None = ormar.ForeignKey(User, ondelete=ReferentialAction.SET_NULL) + size: int = ormar.BigInteger(nullable=False) + storage_path: str | None = ormar.Text(nullable=True) + deleted_at: datetime | None = ormar.DateTime(nullable=True, default=None) + quiztivities: list[QuizTivity] | None = ormar.ManyToMany(QuizTivity) + quizzes: list[Quiz] | None = ormar.ManyToMany(Quiz) + alt_text: str | None = ormar.Text(default=None, nullable=True) + filename: str | None = ormar.Text(default=None, nullable=True) + thumbhash: str | None = ormar.Text(default=None, nullable=True) + server: str | None = ormar.Text(default=None, nullable=True) + imported: bool = ormar.Boolean(default=False, nullable=True) + + class Meta: + tablename = "storage_items" + metadata = metadata + database = database + + +class PublicStorageItem(BaseModel): + id: uuid.UUID + uploaded_at: datetime + mime_type: str + hash: str | None + size: int + deleted_at: datetime | None + alt_text: str | None + filename: str | None + thumbhash: str | None + server: str | None + imported: bool + + @classmethod + def from_db_model(cls, data: StorageItem): + hash_data = None + if data.hash is not None: + hash_data = data.hash.hex() + return cls( + id=data.id, + uploaded_at=data.uploaded_at, + mime_type=data.mime_type, + hash=hash_data, + size=data.size, + deleted_at=data.deleted_at, + alt_text=data.alt_text, + filename=data.filename, + thumbhash=data.thumbhash, + server=data.server, + imported=data.imported, + ) + + +class PrivateStorageItem(PublicStorageItem): + quizzes: list[OnlyId] + quiztivities: list[OnlyId] + + @classmethod + def from_db_model(cls, data: StorageItem): + hash_data = None + if data.hash is not None: + hash_data = data.hash.hex() + quiztivities = [] + quizzes = [] + for quiz in data.quizzes: + quizzes.append(OnlyId(id=quiz.id)) + for quiztivity in data.quiztivities: + quiztivities.append(OnlyId(id=quiztivity.id)) + return cls( + id=data.id, + uploaded_at=data.uploaded_at, + mime_type=data.mime_type, + hash=hash_data, + size=data.size, + deleted_at=data.deleted_at, + alt_text=data.alt_text, + filename=data.filename, + quiztivities=quiztivities, + quizzes=quizzes, + thumbhash=data.thumbhash, + server=data.server, + imported=data.imported, + ) + + +class UpdateStorageItem(BaseModel): + filename: str + alt_text: str diff --git a/classquiz/helpers/__init__.py b/classquiz/helpers/__init__.py index 90dcb66..622ad0e 100644 --- a/classquiz/helpers/__init__.py +++ b/classquiz/helpers/__init__.py @@ -3,6 +3,7 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. import asyncio +import uuid from typing import Optional import ormar.exceptions @@ -64,12 +65,15 @@ async def generate_spreadsheet(quiz_results: dict, quiz: Quiz, player_fields: di worksheet.write(i + 1, 1, question["time"]) try: - async with ClientSession() as session, session.get(question["image"]) as response: - img_data = BytesIO(await response.read()) - worksheet.insert_image(i + 1, 2, question["image"], {"image_data": img_data}) - image = Image.open(img_data) - worksheet.set_row(i + 1, image.height) - worksheet.set_column(2, 2, image.width) + async with ClientSession() as session, session.get( + f"{settings.root_address}/api/v1/storage/download/{question['image']}" + ) as response: + if "image" in response.headers.get("Content-Type"): + img_data = BytesIO(await response.read()) + worksheet.insert_image(i + 1, 2, question["image"], {"image_data": img_data}) + image = Image.open(img_data) + worksheet.set_row(i + 1, image.height) + worksheet.set_column(2, 2, image.width) except TypeError: pass answer_amount = len(answer_data) @@ -175,3 +179,36 @@ def check_hashcash(data: str, input_data: str, claim_in: Optional[str] = "19") - return False some_error = [version == "1", claim == claim_in, res == input_data, ext == ""] return all(el is True for el in some_error) + + +def check_image_string(image: str) -> (bool, uuid.UUID | None): + # Valid formats: {uuid} and {uuid}--{uuid} + try: + parsed_uuid = uuid.UUID(image) + return True, parsed_uuid + except ValueError: + pass + + split_image = image.split("--") + if len(split_image) != 2: + return False, None + + try: + uuid.UUID(split_image[0]) + uuid.UUID(split_image[1]) + return True, None + except ValueError: + return False, None + + +def extract_image_ids_from_quiz(quiz: Quiz) -> list[str | uuid.UUID]: + quiz_images = [] + if quiz.background_image is not None: + quiz_images.append(quiz.background_image) + if quiz.cover_image is not None: + quiz_images.append(quiz.cover_image) + for question in quiz.questions: + if question["image"] is None: + continue + quiz_images.append(question["image"]) + return quiz_images diff --git a/classquiz/helpers/bg_tasks.py b/classquiz/helpers/bg_tasks.py deleted file mode 100644 index 0123a8f..0000000 --- a/classquiz/helpers/bg_tasks.py +++ /dev/null @@ -1,21 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. -from classquiz.config import redis, storage -from classquiz.storage.errors import DeletionFailedError - - -async def clean_editor_images_up(): - print("Cleaning images up") - edit_sessions = await redis.smembers("edit_sessions") - for session_id in edit_sessions: - session = await redis.get(f"edit_session:{session_id}") - if session is None: - images = await redis.lrange(f"edit_session:{session_id}:images", 0, 3000) - if len(images) != 0: - try: - await storage.delete(images) - except DeletionFailedError: - print("Deletion Error", images) - await redis.srem("edit_sessions", session_id) - await redis.delete(f"edit_session:{session_id}:images") diff --git a/classquiz/kahoot_importer/import_quiz.py b/classquiz/kahoot_importer/import_quiz.py index f64dabb..6786c8e 100644 --- a/classquiz/kahoot_importer/import_quiz.py +++ b/classquiz/kahoot_importer/import_quiz.py @@ -3,6 +3,7 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. import html +import io import json import uuid from datetime import datetime @@ -10,8 +11,8 @@ from datetime import datetime import bleach from aiohttp import ClientSession -from classquiz.config import settings, storage, meilisearch, ALLOWED_TAGS_FOR_QUIZ -from classquiz.db.models import Quiz, ABCDQuizAnswer, QuizQuestion, User +from classquiz.config import settings, storage, meilisearch, ALLOWED_TAGS_FOR_QUIZ, arq +from classquiz.db.models import Quiz, ABCDQuizAnswer, QuizQuestion, User, StorageItem from classquiz.kahoot_importer.get import get as get_quiz from classquiz.helpers import get_meili_data @@ -26,6 +27,25 @@ async def _download_image(url: str) -> bytes: DEFAULT_COLORS = ["#D6EDC9", "#B07156", "#7F7057", "#4E6E58"] +async def handle_image_upload(url: str, user: User) -> StorageItem: + image_bytes = await _download_image(url) + file_obj = StorageItem( + id=uuid.uuid4(), + uploaded_at=datetime.now(), + mime_type="application/octet-stream", + hash=None, + user=user, + size=0, + deleted_at=None, + alt_text=None, + imported=True, + ) + await file_obj.save() + await storage.upload(file_name=file_obj.id.hex, file_data=io.BytesIO(image_bytes)) + await arq.enqueue_job("calculate_hash", file_obj.id.hex) + return file_obj + + async def import_quiz(quiz_id: str, user: User) -> Quiz | str: """ Imports a quiz from Kahoot. @@ -41,15 +61,15 @@ async def import_quiz(quiz_id: str, user: User) -> Quiz | str: quiz_id = uuid.uuid4() meilisearch.delete_index(settings.meilisearch_index) meilisearch.create_index(settings.meilisearch_index) + uploaded_images: list[StorageItem] = [] for q in quiz.kahoot.questions: answers: list[ABCDQuizAnswer] = [] image = None if q.image is not None and q.image != "": - image_bytes = await _download_image(q.image) - image_name = f"{quiz_id}--{uuid.uuid4()}" - image = await storage.upload(file_name=image_name, file_data=image_bytes) - image = f"{settings.root_address}/api/v1/storage/download/{image_name}" + image_obj = await handle_image_upload(q.image, user) + uploaded_images.append(image_obj) + image = image_obj.id.hex for i, a in enumerate(q.choices): answers.append( ( @@ -71,10 +91,9 @@ async def import_quiz(quiz_id: str, user: User) -> Quiz | str: ) cover = None if quiz.kahoot.cover != "" and quiz.kahoot.cover is not None: - image_bytes = await _download_image(quiz.kahoot.cover) - image_name = f"{quiz_id}--{uuid.uuid4()}" - await storage.upload(file_name=image_name, file_data=image_bytes) - cover = f"{settings.root_address}/api/v1/storage/download/{image_name}" + img_obj = await handle_image_upload(quiz.kahoot.cover, user) + uploaded_images.append(img_obj) + cover = img_obj.id.hex quiz_data = Quiz( id=quiz_id, public=True, @@ -89,4 +108,7 @@ async def import_quiz(quiz_id: str, user: User) -> Quiz | str: kahoot_id=uuid.UUID(kahoot_quiz_id), ) meilisearch.index(settings.meilisearch_index).add_documents([await get_meili_data(quiz_data)]) - return await quiz_data.save() + await quiz_data.save() + for img in uploaded_images: + await quiz_data.storageitems.add(img) + return quiz_data diff --git a/classquiz/routers/editor.py b/classquiz/routers/editor.py index 98a60ba..7704eab 100644 --- a/classquiz/routers/editor.py +++ b/classquiz/routers/editor.py @@ -4,24 +4,22 @@ import asyncio import html -import re import uuid from typing import Optional import asyncpg.exceptions import bleach -from fastapi import APIRouter, File, UploadFile, HTTPException, Depends +from fastapi import APIRouter, HTTPException, Depends from pydantic import BaseModel -from classquiz.config import settings, redis, storage, meilisearch, ALLOWED_TAGS_FOR_QUIZ, server_regex -from classquiz.db.models import Quiz, QuizInput, User, QuizQuestionType -import puremagic +from classquiz.config import settings, redis, storage, meilisearch, ALLOWED_TAGS_FOR_QUIZ, arq +from classquiz.db.models import Quiz, QuizInput, User, QuizQuestionType, StorageItem from classquiz.auth import get_current_user import os from datetime import datetime from uuid import UUID -from classquiz.helpers import get_meili_data, check_hashcash +from classquiz.helpers import get_meili_data, check_image_string, extract_image_ids_from_quiz from classquiz.storage.errors import DeletionFailedError settings = settings() @@ -67,56 +65,6 @@ async def init_editor(edit: bool, quiz_id: Optional[UUID] = None, user: User = D return InitEditorResponse(token=edit_id) -class GetPowData(BaseModel): - data: str - - -@router.get("/pow", response_model=GetPowData) -async def get_pow_data(edit_id: str): - session_data = await redis.get(f"edit_session:{edit_id}") - if session_data is None: - raise HTTPException(status_code=401, detail="Edit ID not found!") - random_str = os.urandom(8).hex() - await redis.set(f"edit_session:{edit_id}:pow", random_str, ex=3800) - return GetPowData(data=random_str) - - -class UploadImageReturn(BaseModel): - id: str - pow_data: str - - -@router.post("/image", response_model=UploadImageReturn) -async def upload_image(edit_id: str, pow_data: str, file: UploadFile = File()): - session_data = await redis.get(f"edit_session:{edit_id}") - pow_data_server = await redis.get(f"edit_session:{edit_id}:pow") - uploaded_images = await redis.llen(f"edit_session:{edit_id}:images") - if pow_data_server is None: - raise HTTPException(status_code=401, detail="Edit ID not found!") - if session_data is None: - raise HTTPException(status_code=401, detail="Edit ID not found!") - if uploaded_images == 0 and not check_hashcash(pow_data, pow_data_server, "8"): - raise HTTPException(status_code=401, detail="Edit ID not found!") - if uploaded_images != 0 and not check_hashcash(pow_data, pow_data_server, "8"): - raise HTTPException(status_code=401, detail="Edit ID not found!") - file_bytes = await file.read() - if len(file_bytes) > 2000000: - raise HTTPException(status_code=400, detail="File too large") - try: - pm_data = puremagic.magic_string(file_bytes)[0] - except puremagic.PureError: - raise HTTPException(status_code=400, detail="Image couldn't be identified!") - if pm_data.extension not in allowed_image_extensions: - raise HTTPException(status_code=400, detail="Image-type now allowed!") - session_data = EditSessionData.parse_raw(session_data) - file_name = f"{session_data.quiz_id}--{uuid.uuid4()}" - await storage.upload(file_name=file_name, file_data=file_bytes) - await redis.lpush(f"edit_session:{edit_id}:images", file_name) - random_str = os.urandom(8).hex() - await redis.set(f"edit_session:{edit_id}:pow", random_str, ex=3800) - return UploadImageReturn(id=file_name, pow_data=random_str) - - @router.post("/finish") async def finish_edit(edit_id: str, quiz_input: QuizInput): session_data = await redis.get(f"edit_session:{edit_id}") @@ -141,25 +89,10 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput): quiz_input.questions[i].answers[i2].answer = html.unescape( bleach.clean(answer.answer, tags=ALLOWED_TAGS_FOR_QUIZ, strip=True) ) - image_id_regex = r"^.{36}--.{36}$" - imgur_regex = r"^https://i\.imgur\.com\/.{7}.(jpg|png|gif)$" - extract_file_name_re = r"^.*/api/v1/storage/download/(.{36}--.{36})$" images_to_delete = [] old_quiz_data: Quiz = await Quiz.objects.get_or_none(id=session_data.quiz_id, user_id=session_data.user_id) - def mark_image_for_deletion(new: str | None, index: int, old_quiz: Quiz | None): - if old_quiz is None: - return - try: - # Why does this work or not throw an error (TODO) - if new == old_quiz.questions[index]["image"]: - return - else: - images_to_delete.append(old_quiz.questions[index]["image"]) - except IndexError: - pass - for i, question in enumerate(quiz_input.questions): image = question.image quiz_input.questions[i].question = html.unescape( @@ -167,17 +100,7 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput): ) if image == "": question.image = None - mark_image_for_deletion(question.image, i, old_quiz_data) - elif image is None: - mark_image_for_deletion(question.image, i, old_quiz_data) - elif bool(re.match(image_id_regex, question.image)): - question.image = f"{settings.root_address}/api/v1/storage/download/{image}" - mark_image_for_deletion(question.image, i, old_quiz_data) - elif bool(re.match(imgur_regex, image)): - mark_image_for_deletion(question.image, i, old_quiz_data) - elif bool(re.match(server_regex, image)): - mark_image_for_deletion(question.image, i, old_quiz_data) - else: + if image is not None and not check_image_string(image)[0]: raise HTTPException(status_code=400, detail="Image URL(s) aren't valid!") if quiz_input.cover_image == "": @@ -186,10 +109,14 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput): # if quiz_input.background_image is None and old_quiz_data.background_image is not None: # mark_image_for_deletion(quiz_input.background_image) - if quiz_input.cover_image is not None and not bool(re.match(server_regex, quiz_input.cover_image)): + if quiz_input.cover_image is not None and not check_image_string(quiz_input.cover_image)[0]: + raise HTTPException(status_code=400, detail="image url is not valid") + + if quiz_input.background_image is not None and not check_image_string(quiz_input.background_image)[0]: raise HTTPException(status_code=400, detail="image url is not valid") if session_data.edit: + await arq.enqueue_job("quiz_update", old_quiz_data, old_quiz_data.id, _defer_by=2) quiz = old_quiz_data meilisearch.index(settings.meilisearch_index).update_documents([await get_meili_data(quiz)]) if not quiz_input.public: @@ -207,13 +134,14 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput): for image in images_to_delete: if image is not None: try: - await storage.delete([re.search(extract_file_name_re, image).group(1)]) + await storage.delete([image]) except DeletionFailedError: pass await redis.srem("edit_sessions", edit_id) await redis.delete(f"edit_session:{edit_id}") await redis.delete(f"edit_session:{edit_id}:images") - return await quiz.update() + await quiz.update() + return quiz else: quiz = Quiz( **quiz_input.dict(), @@ -222,6 +150,7 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput): created_at=datetime.now(), updated_at=datetime.now(), ) + await redis.delete("global_quiz_count") if quiz_input.public: meilisearch.index(settings.meilisearch_index).add_documents([await get_meili_data(quiz)]) @@ -229,6 +158,12 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput): await redis.srem("edit_sessions", edit_id) await redis.delete(f"edit_session:{edit_id}") await redis.delete(f"edit_session:{edit_id}:images") - return await quiz.save() + await quiz.save() except asyncpg.exceptions.UniqueViolationError: raise HTTPException(status_code=400, detail="The quiz already exists") + new_images = extract_image_ids_from_quiz(quiz) + for image in new_images: + item = await StorageItem.objects.get_or_none(id=uuid.UUID(image)) + if item is None: + continue + await quiz.storageitems.add(item) diff --git a/classquiz/routers/eximport.py b/classquiz/routers/eximport.py index 56758b0..294548b 100644 --- a/classquiz/routers/eximport.py +++ b/classquiz/routers/eximport.py @@ -1,6 +1,7 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. +import io import json import uuid from datetime import datetime @@ -10,10 +11,11 @@ from aiohttp import ClientSession from fastapi import APIRouter, Depends, File, UploadFile, HTTPException from fastapi.responses import StreamingResponse from classquiz.auth import get_current_user -from classquiz.config import storage, settings -from classquiz.db.models import Quiz, User +from classquiz.config import storage, settings, arq +from classquiz.db.models import Quiz, User, StorageItem import gzip import urllib.parse +import magic router = APIRouter() settings = settings() @@ -49,7 +51,9 @@ async def export_quiz(quiz_id: uuid.UUID, user: User = Depends(get_current_user) for image_key in image_urls.keys(): bin_data = bin_data + image_delimiter + str(image_key).encode("utf-8") + image_index_delimiter image_data = None - async with ClientSession() as session, session.get(image_urls[image_key]) as resp: + async with ClientSession() as session, session.get( + f"{settings.root_address}/api/v1/storage/download/{image_urls[image_key]}" + ) as resp: image_data = await resp.read() bin_data = bin_data + image_data @@ -68,6 +72,8 @@ async def export_quiz(quiz_id: uuid.UUID, user: User = Depends(get_current_user) @router.post("/") async def import_quiz(file: UploadFile = File(), user: User = Depends(get_current_user)): + if user.storage_used > settings.free_storage_limit: + raise HTTPException(status_code=409, detail="Storage limit reached") data = await file.read() [split_data, images] = data.split(quiz_delimiter) decompressed_quiz = gzip.decompress(split_data) @@ -75,15 +81,32 @@ async def import_quiz(file: UploadFile = File(), user: User = Depends(get_curren image_splits = images.split(image_delimiter) quiz_id = uuid.uuid4() image_urls = {} + print(len(data)) for image_split in image_splits: res = image_split.split(image_index_delimiter) if len(res) != 2: continue [index, image_data] = res + print(len(image_data)) + img_data = io.BytesIO(image_data) + mime_type = magic.from_buffer(img_data.read(2048), mime=True) + print(mime_type) index = int(index.decode("utf-8")) - image_name = f"{quiz_id}--{uuid.uuid4()}" - await storage.upload(file_name=image_name, file_data=image_data) - image = f"{settings.root_address}/api/v1/storage/download/{image_name}" + file_id = uuid.uuid4() + file_obj = StorageItem( + id=file_id, + uploaded_at=datetime.now(), + mime_type=mime_type, + hash=None, + user=user, + size=0, + deleted_at=None, + alt_text=None, + ) + await storage.upload(file_name=file_id.hex, file_data=img_data, mime_type=mime_type) + await file_obj.save() + await arq.enqueue_job("calculate_hash", file_id.hex) + image = file_id.hex image_urls[index] = image quiz_dict["created_at"] = datetime.fromisoformat(quiz_dict["created_at"]) quiz_dict["updated_at"] = datetime.fromisoformat(quiz_dict["updated_at"]) diff --git a/classquiz/routers/quiz.py b/classquiz/routers/quiz.py index 2ab1c06..3069cb9 100644 --- a/classquiz/routers/quiz.py +++ b/classquiz/routers/quiz.py @@ -11,17 +11,15 @@ from random import randint import ormar.exceptions -from classquiz.helpers import get_meili_data, generate_spreadsheet +from classquiz.helpers import generate_spreadsheet from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import JSONResponse, StreamingResponse from pydantic import ValidationError, BaseModel -import bleach from classquiz.auth import get_current_user from classquiz.config import redis, settings, storage, meilisearch -from classquiz.db.models import Quiz, QuizInput, User, PlayGame, GameInLobby, QuizQuestion +from classquiz.db.models import Quiz, User, PlayGame, GameInLobby, QuizQuestion from classquiz.kahoot_importer.import_quiz import import_quiz -import html import urllib.parse settings = settings() @@ -29,33 +27,6 @@ settings = settings() router = APIRouter() -@router.post("/create", deprecated=True) -async def create_quiz_lol(quiz_input: QuizInput, user: User = Depends(get_current_user)): - imgur_regex = r"^https://i\.imgur\.com\/.{7}.(jpg|png|gif)$" - server_regex = rf"^{re.escape(settings.root_address)}/api/v1/storage/download/.{36}--.{36}$" - quiz_input.title = html.unescape(bleach.clean(quiz_input.title, tags=[], strip=True)) - quiz_input.description = html.unescape(bleach.clean(quiz_input.description, tags=[], strip=True)) - for question in quiz_input.questions: - if question.image == "": - question.image = None - if ( - question.image is not None - and not re.match(imgur_regex, question.image) - and not re.match(server_regex, question.image) - ): - raise HTTPException(status_code=400, detail="image url is not valid") - if quiz_input.cover_image == "": - quiz_input.cover_image = None - - if quiz_input.cover_image is not None and not bool(re.match(server_regex, quiz_input.cover_image)): - raise HTTPException(status_code=400, detail="image url is not valid") - quiz = Quiz(**quiz_input.dict(), user_id=user.id, id=uuid.uuid4()) - await redis.delete("global_quiz_count") - if quiz_input.public: - meilisearch.index(settings.meilisearch_index).add_documents([await get_meili_data(quiz)]) - return await quiz.save() - - @router.get("/get/{quiz_id}") async def get_quiz_from_id(quiz_id: str, user: User | None = Depends(get_current_user)): try: @@ -213,57 +184,14 @@ async def get_quiz_list(user: User = Depends(get_current_user), page_size: int | raise HTTPException(status_code=400, detail="Invalid page(size). page(size) have to be greater than 0.") -@router.put("/update/{quiz_id}", deprecated=True) -async def update_quiz(quiz_id: str, quiz_input: QuizInput, user: User = Depends(get_current_user)): - imgur_regex = r"^https://i\.imgur\.com\/.{7}.(jpg|png|gif)$" - server_regex = rf"^{re.escape(settings.root_address)}/api/v1/storage/download/.{{36}}--.{{36}}$" - for question in quiz_input.questions: - if question.image == "": - question.image = None - if ( - question.image is not None - and not bool(re.match(server_regex, question.image)) - and not bool(re.match(imgur_regex, question.image)) - ): - raise HTTPException(status_code=400, detail="image url is not valid") - try: - quiz_id = uuid.UUID(quiz_id) - except ValueError: - raise HTTPException(status_code=400, detail="badly formed quiz id") - # Check Cover-Image - - if quiz_input.cover_image == "": - quiz_input.cover_image = None - - if quiz_input.cover_image is not None and not bool(re.match(server_regex, quiz_input.cover_image)): - raise HTTPException(status_code=400, detail="image url is not valid") - - quiz = await Quiz.objects.get_or_none(id=quiz_id, user_id=user.id) - if quiz is None: - return JSONResponse(status_code=404, content={"detail": "quiz not found"}) - else: - quiz_input.description = html.unescape(bleach.clean(quiz_input.description, tags=[], strip=True)) - quiz_input.title = html.unescape(bleach.clean(quiz_input.title, tags=[], strip=True)) - meilisearch.index(settings.meilisearch_index).update_documents([await get_meili_data(quiz)]) - if quiz.public and not quiz_input.public: - meilisearch.index(settings.meilisearch_index).delete_document(str(quiz.id)) - if not quiz.public and quiz_input.public: - meilisearch.index(settings.meilisearch_index).add_documents([await get_meili_data(quiz)]) - quiz.title = quiz_input.title - quiz.cover_image = quiz_input.cover_image - quiz.public = quiz_input.public - quiz.description = quiz_input.description - quiz.updated_at = datetime.now() - quiz.questions = quiz_input.dict()["questions"] - - return await quiz.update() - - @router.post("/import/{quiz_id}") async def import_quiz_route(quiz_id: str, user: User = Depends(get_current_user)): + if user.storage_used > settings.free_storage_limit: + raise HTTPException(status_code=409, detail="Storage limit reached") try: return await import_quiz(quiz_id, user) - except ValidationError: + except ValidationError as e: + print(e) raise HTTPException(status_code=400, detail="This quiz isn't (yet) supported") @@ -282,7 +210,9 @@ async def delete_quiz(quiz_id: str, user: User = Depends(get_current_user)): for question in quiz.questions: try: if question["image"] is not None and not str(question["image"]).startswith("https://i.imgur.com/"): - pics_to_delete.append(pic_name_regex.match(question["image"]).group(1)) + old_image_to_delete = pic_name_regex.match(question["image"]) + if old_image_to_delete is not None: + pics_to_delete.append(old_image_to_delete.group(1)) except KeyError: pass if len(pics_to_delete) != 0: diff --git a/classquiz/routers/storage.py b/classquiz/routers/storage.py index ea10a8a..17e4792 100644 --- a/classquiz/routers/storage.py +++ b/classquiz/routers/storage.py @@ -1,29 +1,53 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. +from datetime import datetime, timedelta +from tempfile import SpooledTemporaryFile -import re - -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, UploadFile, File, Depends, Request, Response from fastapi.responses import StreamingResponse, RedirectResponse +from pydantic import BaseModel -from classquiz.config import settings, storage +from classquiz.auth import get_current_user +from classquiz.config import settings, storage, arq +from classquiz.db.models import User, StorageItem, PublicStorageItem, UpdateStorageItem, PrivateStorageItem +from classquiz.helpers import check_image_string from classquiz.storage.errors import DownloadingFailedError +from uuid import uuid4, UUID settings = settings() router = APIRouter() -file_regex = r"^[a-z0-9]{8}-[a-z0-9-]{27}--[a-z0-9-]{36}$" + +def headers_from_storage_item(item: StorageItem) -> dict[str, str]: + base_headers = {"Content-Type": item.mime_type} + if item.hash is not None: + base_headers["X-Hash"] = item.hash.hex() + if item.thumbhash is not None: + base_headers["X-Thumbhash"] = item.thumbhash + if item.alt_text is not None: + base_headers["X-Alt-Text"] = item.alt_text + if item.size != 0: + base_headers["Content-Size"] = str(item.size) + return base_headers @router.get("/download/{file_name}") async def download_file(file_name: str): - if not re.match(file_regex, file_name): + item = None + checked_image_string = check_image_string(file_name) + if not checked_image_string[0]: raise HTTPException(status_code=400, detail="Invalid file name") + if checked_image_string[1] is not None: + item = await StorageItem.objects.get_or_none(id=checked_image_string[1]) + if item is None: + raise HTTPException(status_code=404, detail="File not found") + file_name = item.storage_path + if file_name is None: + file_name = item.id.hex if storage.backend == "s3": - print("redir") - return RedirectResponse(url=await storage.get_url(file_name, 300)) + return RedirectResponse(url=await storage.get_url(file_name, 300), headers=headers_from_storage_item(item)) try: download = await storage.download(file_name) except DownloadingFailedError: @@ -34,8 +58,198 @@ async def download_file(file_name: str): def iter_file(): yield from download + media_type = "image/*" + if item is not None: + media_type = item.mime_type + headers = {"Cache-Control": "public, immutable, max-age=31536000"} + if item is not None: + headers = {**headers, **headers_from_storage_item(item)} + return StreamingResponse( iter_file(), - media_type="image/*", - headers={"Cache-Control": "public, immutable, max-age=31536000"}, + media_type=media_type, + headers=headers, ) + + +@router.get("/info/{file_name}") +async def get_basic_file_info(file_name: str) -> Response: + checked_image_string = check_image_string(file_name) + if not checked_image_string[0]: + raise HTTPException(status_code=404, detail="Invalid file name") + if checked_image_string[1] is not None: + item = await StorageItem.objects.get_or_none(id=checked_image_string[1]) + if item is None: + raise HTTPException(status_code=404, detail="File not found") + # return PublicStorageItem.from_db_model(item) + storage_file_name = item.storage_path + if storage_file_name is None: + storage_file_name = item.id.hex + resp = Response(status_code=200, headers=headers_from_storage_item(item)) + else: + resp = Response(status_code=200, headers={"Content-Type": "image/*"}) + return resp + + +@router.head("/download/{file_name}") +async def download_file_head(file_name: str) -> Response: + checked_image_string = check_image_string(file_name) + if not checked_image_string[0]: + raise HTTPException(status_code=404, detail="Invalid file name") + if checked_image_string[1] is not None: + item = await StorageItem.objects.get_or_none(id=checked_image_string[1]) + if item is None: + raise HTTPException(status_code=404, detail="File not found") + # return PublicStorageItem.from_db_model(item) + storage_file_name = item.storage_path + if storage_file_name is None: + storage_file_name = item.id.hex + resp = Response(status_code=200, headers=headers_from_storage_item(item)) + else: + resp = Response(status_code=200, headers={"Content-Type": "image/*"}) + storage_file_name = file_name + if storage.backend == "s3": + resp.status_code = 307 + resp.headers.append("Location", await storage.get_url(storage_file_name, 300)) + return resp + + +@router.post("/") +async def upload_file(file: UploadFile = File(), user: User = Depends(get_current_user)) -> PublicStorageItem: + if user.storage_used > settings.free_storage_limit: + raise HTTPException(status_code=409, detail="Storage limit reached") + file_id = uuid4() + + size = 0 + file_obj = StorageItem( + id=file_id, + uploaded_at=datetime.now(), + mime_type=file.content_type, + hash=None, + user=user, + size=size, + deleted_at=None, + alt_text=None, + ) + await storage.upload(file_name=file_id.hex, file_data=file.file, mime_type=file.content_type) + await file_obj.save() + await arq.enqueue_job("calculate_hash", file_id.hex) + return PublicStorageItem.from_db_model(file_obj) + + +@router.post("/raw") +async def upload_raw_file(request: Request, user: User = Depends(get_current_user)) -> PublicStorageItem: + if user.storage_used > settings.free_storage_limit: + raise HTTPException(status_code=409, detail="Storage limit reached") + file_id = uuid4() + data_file = SpooledTemporaryFile(max_size=1000) + async for chunk in request.stream(): + data_file.write(chunk) + data_file.seek(0) + file_obj = StorageItem( + id=file_id, + uploaded_at=datetime.now(), + mime_type=request.headers.get("Content-Type"), + hash=None, + user=user, + size=0, + deleted_at=None, + alt_text=None, + ) + # https://github.com/VirusTotal/vt-py/issues/119#issuecomment-1261246867 + await storage.upload( + file_name=file_id.hex, file_data=data_file._file, mime_type=request.headers.get("Content-Type") + ) + await file_obj.save() + await arq.enqueue_job("calculate_hash", file_id.hex) + return PublicStorageItem.from_db_model(file_obj) + + +@router.get("/meta/{file_id}") +async def get_file_info(file_id: UUID, user: User = Depends(get_current_user)) -> PublicStorageItem: + file_data = await StorageItem.objects.get_or_none(id=file_id, user=user, deleted_at=None) + if file_data is None: + raise HTTPException(status_code=404, detail="File not found") + return PublicStorageItem.from_db_model(file_data) + + +@router.delete("/meta/{file_id}") +async def mark_file_as_deleted(file_id: UUID, user: User = Depends(get_current_user)): + file_data = await StorageItem.objects.get_or_none(id=file_id, user=user, deleted_at=None) + if file_data is None: + raise HTTPException(status_code=404, detail="File not found") + storage_path = file_data.storage_path + if storage_path is None: + storage_path = file_data.id.hex + await storage.delete(storage_path) + file_data.deleted_at = datetime.now() + await file_data.update() + return + + +@router.put("/meta/{file_id}") +async def update_image_data( + file_id: UUID, data: UpdateStorageItem, user: User = Depends(get_current_user) +) -> PublicStorageItem: + file_data = await StorageItem.objects.get_or_none(id=file_id, user=user, deleted_at=None) + if file_data is None: + raise HTTPException(status_code=404, detail="File not found") + file_data.filename = data.filename + file_data.alt_text = data.alt_text + await file_data.update() + return PublicStorageItem.from_db_model(file_data) + + +@router.get("/list") +async def list_images( + since: datetime | None = None, user: User = Depends(get_current_user) +) -> list[PrivateStorageItem]: + if since is None: + since = datetime.now() - timedelta(days=2) + storage_items = ( + await StorageItem.objects.filter(user=user) + .filter(StorageItem.uploaded_at > since) + .filter(StorageItem.deleted_at == None) # noqa: E711 + .order_by(StorageItem.uploaded_at.desc()) + .select_related([StorageItem.quizzes, StorageItem.quiztivities]) + .all() + ) + if len(storage_items) == 0: + raise HTTPException(status_code=404, detail="No items found") + return_items: list[PrivateStorageItem] = [] + for item in storage_items: + # print(item.quizzes) + return_items.append(PrivateStorageItem.from_db_model(item)) + return return_items + + +@router.get("/list/last") +async def get_latest_images(count: int = 50, user: User = Depends(get_current_user)) -> list[PrivateStorageItem]: + if count > 50: + count = 50 + items = ( + await StorageItem.objects.filter(user=user) + .limit(count) + .select_related([StorageItem.quizzes, StorageItem.quiztivities]) + .order_by(StorageItem.uploaded_at.desc()) + .all() + ) + return_items: list[PrivateStorageItem] = [] + for item in items: + return_items.append(PrivateStorageItem.from_db_model(item)) + return return_items + + +class ReturnGetStorageLimit(BaseModel): + limit: int + limit_reached: bool + used: int + + +@router.get("/limit") +async def get_storage_limit(user: User = Depends(get_current_user)) -> ReturnGetStorageLimit: + user = await User.objects.get_or_none(id=user.id) + if user.storage_used > settings.free_storage_limit: + return ReturnGetStorageLimit(limit=settings.free_storage_limit, limit_reached=True, used=user.storage_used) + else: + return ReturnGetStorageLimit(limit=settings.free_storage_limit, limit_reached=False, used=user.storage_used) diff --git a/classquiz/storage/__init__.py b/classquiz/storage/__init__.py index 92e1c5a..88469b1 100644 --- a/classquiz/storage/__init__.py +++ b/classquiz/storage/__init__.py @@ -2,20 +2,17 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -from io import BytesIO -from typing import Optional +from typing import Optional, BinaryIO -from .deta_storage import DetaStorage from .local_storage import LocalStorage from .s3_storage import S3Storage +from typing import Generator class Storage: def __init__( self, backend: str, - deta_key: Optional[str], - deta_id: Optional[str], storage_path: Optional[str], access_key: str | None = None, secret_key: str | None = None, @@ -23,65 +20,45 @@ class Storage: base_url: str | None = None, ): self.backend = backend - self.deta_key: str | None = deta_key - self.deta_id: str | None = deta_id - # self.deta_base_url = f"https://drive.deta.sh/v1/{deta_id}/classquiz1" self.access_key = access_key self.secret_key = secret_key self.bucket_name = bucket_name self.base_url = base_url - self.deta_instance = None - if backend == "deta": - if deta_key is None or deta_id is None: - raise ValueError("deta_key and deta_id must be provided") - if self.base_url is None: - self.base_url = f"https://drive.deta.sh/v1/{deta_id}/classquiz1" - self.deta_instance = DetaStorage( - deta_base_url=self.base_url, - deta_key=self.deta_key, - deta_id=self.deta_id, - ) + self.instance: LocalStorage | S3Storage | None = None - elif backend == "local": + if backend == "local": if storage_path is None: raise ValueError("storage_path must be provided") else: - self.local_instance = LocalStorage(base_path=storage_path) + self.instance = LocalStorage(base_path=storage_path) elif backend == "s3": if access_key is None or secret_key is None or bucket_name is None or base_url is None: raise ValueError("Not all parameters given") - self.s3_instance = S3Storage( + self.instance = S3Storage( base_url=base_url, access_key=access_key, secret_key=secret_key, bucket_name=bucket_name ) else: raise NotImplementedError(f"Backend {backend} not implemented") - async def download(self, file_name: str) -> BytesIO | None: - if self.backend == "deta": - return await self.deta_instance.download(file_name) - elif self.backend == "local": - return await self.local_instance.get_file(file_name) - elif self.backend == "s3": - return await self.s3_instance.download(file_name) + async def download(self, file_name: str) -> Generator | None: + """ + No support for s3 since it doesn't make sense relaying the traffic through this backend + :param file_name: + :return: + """ + yield self.instance.download(file_name) - async def upload(self, file_name: str, file_data: bytes) -> None: - if self.backend == "deta": - return await self.deta_instance.upload(file=file_data, file_name=file_name) - elif self.backend == "local": - return await self.local_instance.write_file(file_name=file_name, data=file_data) - elif self.backend == "s3": - return await self.s3_instance.upload(file=file_data, file_name=file_name) + async def upload(self, file_name: str, file_data: BinaryIO, mime_type: str | None = None) -> None: + return await self.instance.upload(file=file_data, file_name=file_name, mime_type=mime_type) async def delete(self, file_names: [str]) -> None: - if self.backend == "deta": - return await self.deta_instance.delete(file_names=file_names) - elif self.backend == "local": - return await self.local_instance.delete_file(file_names=file_names) - elif self.backend == "s3": - return await self.s3_instance.delete(file_names=file_names) + return await self.instance.delete(file_names=file_names) async def get_url(self, file_name: str, expiry: int) -> str: if self.backend == "s3": - return self.s3_instance.get_url(file_name=file_name, expire=expiry) + return self.instance.get_url(file_name=file_name, expire=expiry) + + async def get_file_size(self, file_name: str) -> int | None: + return self.instance.size(file_name) diff --git a/classquiz/storage/deta_storage.py b/classquiz/storage/deta_storage.py deleted file mode 100644 index 4620f16..0000000 --- a/classquiz/storage/deta_storage.py +++ /dev/null @@ -1,58 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -from io import BytesIO -from classquiz.storage.errors import DeletionFailedError, SavingFailedError, DownloadingFailedError - -from aiohttp import ClientSession - - -class DetaStorage: - def __init__(self, deta_base_url: str, deta_id: str, deta_key: str): - self.deta_url = deta_base_url - self.deta_id = deta_id - self.deta_key = deta_key - self.headers = { - "X-Api-Key": self.deta_key, - } - - async def download(self, file_name: str) -> BytesIO | None: - """ - - :param file_name: The name of the file to be downloaded - :return: Either bytes if successful download or None if failed - """ - async with ClientSession(headers=self.headers) as session, session.get( - f"{self.deta_url}/files/download?name={file_name}" - ) as response: - if response.status == 200: - return BytesIO(await response.read()) - elif response.status == 404: - return None - else: - raise DownloadingFailedError - - async def upload(self, file: bytes, file_name: str) -> None: - """ - :param file: The file in bytes - :param file_name: The name of the file - :return: - """ - async with ClientSession(headers=self.headers) as session, session.post( - f"{self.deta_url}/files?name={file_name}", data=file - ) as response: - if response.status == 201: - return None - else: - print(response.status, await response.json()) - raise SavingFailedError - - async def delete(self, file_names: [str]) -> None: - async with ClientSession(headers=self.headers) as session, session.delete( - f"{self.deta_url}/files", json={"names": file_names} - ) as response: - if response.status == 200: - return None - else: - raise DeletionFailedError diff --git a/classquiz/storage/local_storage.py b/classquiz/storage/local_storage.py index e75dbdd..a352ee8 100644 --- a/classquiz/storage/local_storage.py +++ b/classquiz/storage/local_storage.py @@ -2,32 +2,45 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at https://mozilla.org/MPL/2.0/. -import io import os +from typing import BinaryIO, Generator import aiofiles import aiofiles.os +_DEFAULT_CHUNK_SIZE = 32768 # bytes; arbitrary + + +async def aioshutil_copyfileobj(async_fsrc, async_fdst, *, chunksize: int = _DEFAULT_CHUNK_SIZE) -> None: + while (chunk := await async_fsrc.read(chunksize)) != b"": + await async_fdst.write(chunk) + class LocalStorage: def __init__(self, base_path: str): self.base_path = base_path - async def get_file(self, file_name: str) -> io.BytesIO | None: + async def download(self, file_name: str) -> Generator | None: try: async with aiofiles.open(file=os.path.join(self.base_path, file_name), mode="rb") as f: - return io.BytesIO(await f.read()) + yield f.read() except FileNotFoundError: - return None + yield None - async def write_file(self, file_name: str, data: bytes) -> None: + async def upload(self, file_name: str, data: BinaryIO, mime_type: str | None = None) -> None: async with aiofiles.open(file=os.path.join(self.base_path, file_name), mode="wb") as f: - await f.write(data) + await aioshutil_copyfileobj(data, f) - async def delete_file(self, file_names: [str]) -> None: + async def delete(self, file_names: [str]) -> None: for i in file_names: try: await aiofiles.os.remove(os.path.join(self.base_path, i)) except FileNotFoundError: pass return None + + def size(self, file_name: str) -> int | None: + try: + return os.stat(os.path.join(self.base_path, file_name)) + except FileNotFoundError: + return None diff --git a/classquiz/storage/s3_storage.py b/classquiz/storage/s3_storage.py index 4f499f0..6a1470d 100644 --- a/classquiz/storage/s3_storage.py +++ b/classquiz/storage/s3_storage.py @@ -8,8 +8,7 @@ import hashlib import hmac from datetime import datetime, timedelta -from io import BytesIO -from typing import Tuple +from typing import Tuple, BinaryIO, Generator from aiohttp import ClientSession import minio @@ -113,17 +112,7 @@ class S3Storage: return headers, request_url - async def download(self, file_name: str): - headers, url = self._generate_aws_signature_v4(method="GET", path=f"/{file_name}") - async with ClientSession() as session, session.get(url, headers=headers) as resp: - if resp.status == 200: - return BytesIO(await resp.read()) - elif resp.status == 404: - return None - else: - raise DownloadingFailedError - - async def upload(self, file: bytes, file_name: str, content_type: str | None = "application/octet-stream") -> None: + async def upload(self, file: BinaryIO, file_name: str, mime_type: str | None = "application/octet-stream") -> None: headers, url = self._generate_aws_signature_v4(method="PUT", path=f"/{file_name}") async with ClientSession() as session, session.put(url, headers=headers, data=file) as resp: if resp.status == 200: @@ -145,3 +134,25 @@ class S3Storage: return self.client.presigned_get_object( object_name=file_name, bucket_name=self.bucket_name, expires=timedelta(seconds=expire) ) + + def size(self, file_name: str) -> int | None: + res = self.client.stat_object(bucket_name=self.bucket_name, object_name=file_name) + if res is None: + return None + return res.size + + async def download(self, file_name: str) -> Generator: + headers, url = self._generate_aws_signature_v4(method="GET", path=f"/{file_name}") + + async with ClientSession() as session, session.get(url, headers=headers) as resp: + if resp.status == 200: + async for i in resp.content.iter_chunked(1024): + yield i + elif resp.status == 404: + yield None + else: + raise DownloadingFailedError + # client = httpx.AsyncClient() + # async with client.stream("GET", url, headers=headers) as resp: + # if resp.status == 200: + # yield resp.aiter_bytes() diff --git a/classquiz/worker/__init__.py b/classquiz/worker/__init__.py new file mode 100644 index 0000000..9e4e05e --- /dev/null +++ b/classquiz/worker/__init__.py @@ -0,0 +1,29 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +from arq import cron +from arq.connections import RedisSettings + +from classquiz import settings +from classquiz.db import database +from classquiz.worker.storage import clean_editor_images_up, calculate_hash, quiz_update + + +async def startup(ctx): + ctx["db"] = database + if not ctx["db"].is_connected: + await ctx["db"].connect() + + +async def shutdown(ctx): + if ctx["db"].is_connected: + await ctx["db"].disconnect() + + +class WorkerSettings: + # functions = [add_track] + functions = [calculate_hash, quiz_update] + cron_jobs = [cron(clean_editor_images_up, hour={0, 6, 12, 18}, minute=0)] + on_startup = startup + on_shutdown = shutdown + redis_settings = RedisSettings.from_dsn(settings.redis) diff --git a/classquiz/worker/storage.py b/classquiz/worker/storage.py new file mode 100644 index 0000000..2ada401 --- /dev/null +++ b/classquiz/worker/storage.py @@ -0,0 +1,108 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +import uuid + +import ormar.exceptions +from arq.worker import Retry +import xxhash + +from classquiz.config import redis, storage +from tempfile import SpooledTemporaryFile + +from classquiz.db.models import StorageItem, Quiz, User +from classquiz.helpers import extract_image_ids_from_quiz +from classquiz.storage.errors import DeletionFailedError +from thumbhash import image_to_thumbhash + + +async def clean_editor_images_up(ctx): + print("Cleaning images up") + edit_sessions = await redis.smembers("edit_sessions") + for session_id in edit_sessions: + session = await redis.get(f"edit_session:{session_id}") + if session is None: + images = await redis.lrange(f"edit_session:{session_id}:images", 0, 3000) + if len(images) != 0: + try: + await storage.delete(images) + except DeletionFailedError: + print("Deletion Error", images) + await redis.srem("edit_sessions", session_id) + await redis.delete(f"edit_session:{session_id}:images") + + +async def calculate_hash(ctx, file_id_as_str: str): + file_id = uuid.UUID(file_id_as_str) + file_data: StorageItem = await StorageItem.objects.select_related(StorageItem.user).get(id=file_id) + file_path = file_id.hex + if file_data.storage_path is not None: + file_path = file_data.storage_path + file = SpooledTemporaryFile() + file_data.size = await storage.get_file_size(file_name=file_path) + if file_data.size is None: + file_data.size = 0 + file_bytes = storage.download(file_path) + if file_bytes is None: + print("Retry raised!") + raise Retry(defer=ctx["job_try"] * 10) + async for chunk in file_bytes: + async for c in chunk: + file.write(c) + + if 0 < file_data.size < 20_970_000: # greater than 0 but smaller than 20mbytes + file_data.thumbhash = image_to_thumbhash(file) + hash_obj = xxhash.xxh3_128() + + # assert hash_obj.block_size == 64 + while chunk := file.read(6400): + hash_obj.update(chunk) + file_data.hash = hash_obj.digest() + print("Got hash!") + await file_data.update() + file.close() + user: User | None = await User.objects.get_or_none(id=file_data.user.id) + if user is None: + return + user.storage_used += file_data.size + await user.update() + + +async def quiz_update(ctx, old_quiz: Quiz, quiz_id: uuid.UUID): + new_quiz: Quiz = await Quiz.objects.get(id=quiz_id) + old_images = extract_image_ids_from_quiz(old_quiz) + new_images = extract_image_ids_from_quiz(new_quiz) + + # If images are identical, then return + if sorted(old_images) == sorted(new_images): + print("Nothing's changed") + return + print("Change detected") + removed_images = list(set(old_images) - set(new_images)) + added_images = list(set(new_images) - set(old_images)) + change_made = False + # print("added:", added_images) + # print("removed:", removed_images) + for image in removed_images: + if "--" in image: + await storage.delete([image]) + else: + item = await StorageItem.objects.get_or_none(id=uuid.UUID(image)) + if item is None: + continue + # print("removed item") + try: + await new_quiz.storageitems.remove(item) + except ormar.exceptions.NoMatch: + continue + change_made = True + for image in added_images: + if "--" not in image: + item = await StorageItem.objects.get_or_none(id=uuid.UUID(image)) + if item is None: + continue + # print("added item") + await new_quiz.storageitems.add(item) + change_made = True + if change_made: + await new_quiz.update() diff --git a/docker-compose.yml b/docker-compose.yml index 6ebbab4..29b7ff0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,16 +13,17 @@ services: REDIS_URL: redis://redis:6379/0?decode_responses=True API_URL: http://api:80 api: - build: + build: &build_cfg context: . dockerfile: Dockerfile - restart: always - depends_on: + restart: &restart always + depends_on: &depends - db - redis - environment: + environment: &env_vars DB_URL: "postgresql://postgres:classquiz@db:5432/classquiz" + REDIS: "redis://redis:6379/0?decode_responses=True" MAIL_ADDRESS: "email@email@email.email" MAIL_PASSWORD: "PASSWORT" MAIL_USERNAME: "email@email@email.email" @@ -34,6 +35,8 @@ services: SKIP_EMAIL_VERIFICATION: True HCAPTCHA_KEY: "HCAPTCHA_PRIVATE_KEY" MEILISEARCH_URL: "http://meilisearch:7700" + STORAGE_BACKEND: "local" + STORAGE_PATH: "/app/data" redis: image: redis:alpine restart: always @@ -67,6 +70,14 @@ services: MEILI_NO_ANALYTICS: true volumes: - meilisearch-data:/data.ms + worker: + build: *build_cfg + environment: *env_vars + depends_on: *depends + restart: *restart + command: arq classquiz.worker.WorkerSettings + + volumes: data: meilisearch-data: diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 9c5fbb9..ad25ef4 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -22,7 +22,7 @@ COPY package*.json ./ COPY pnpm-lock.yaml ./ # run npm install in our local machine -RUN corepack enable && corepack prepare pnpm@7.26.2 --activate && pnpm i +RUN corepack enable && corepack prepare pnpm@8.6.1 --activate && pnpm i # copy the generated modules and all other files to the container COPY . . @@ -38,7 +38,7 @@ FROM node:19-bullseye-slim WORKDIR /app COPY --from=builder /usr/src/app/package.json . COPY --from=builder /usr/src/app/pnpm-lock.yaml . -RUN corepack enable && corepack prepare pnpm@7.26.2 --activate && pnpm i +RUN corepack enable && corepack prepare pnpm@8.6.1 --activate && pnpm i # copy files from previous step COPY --from=builder /usr/src/app/build . COPY --from=builder /usr/src/app/node_modules ./node_modules diff --git a/frontend/package.json b/frontend/package.json index cf535b5..2b0e6ee 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,6 +23,8 @@ "@ckeditor/ckeditor5-theme-lark": "^37.1.0", "@felte/reporter-tippy": "^1.1.5", "@felte/validator-yup": "^1.0.11", + "@ffmpeg/core": "^0.11.0", + "@ffmpeg/ffmpeg": "^0.11.6", "@fontsource/marck-script": "^4.5.11", "@sentry/browser": "^7.48.0", "@sentry/tracing": "^7.48.0", @@ -42,6 +44,7 @@ "@types/ua-parser-js": "^0.7.36", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", + "@unlazy/svelte": "^0.8.9", "@uppy/compressor": "^1.0.2", "@uppy/core": "^3.2.0", "@uppy/dashboard": "^3.4.0", @@ -89,11 +92,13 @@ "svelte-tippy": "^1.3.2", "swiper": "^8.4.7", "tailwindcss": "^3.3.1", + "thumbhash": "^0.1.1", "tippy.js": "^6.3.7", "tslib": "^2.5.0", "typescript": "~5.0.4", "ua-parser-js": "^1.0.35", "vite": "^4.2.2", + "vite-plugin-cross-origin-isolation": "^0.1.6", "vite-plugin-iso-import": "^1.0.0", "yup": "^1.1.1" }, diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 797eb29..a575a41 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,179 +1,279 @@ -lockfileVersion: 5.4 +lockfileVersion: '6.1' -specifiers: - '@beyonk/svelte-mapbox': ^9.0.5 - '@ckeditor/ckeditor5-autoformat': ^37.1.0 - '@ckeditor/ckeditor5-basic-styles': ^37.1.0 - '@ckeditor/ckeditor5-build-balloon': ^37.1.0 - '@ckeditor/ckeditor5-editor-balloon': ^37.1.0 - '@ckeditor/ckeditor5-essentials': ^37.1.0 - '@ckeditor/ckeditor5-theme-lark': ^37.1.0 - '@felte/reporter-tippy': ^1.1.5 - '@felte/validator-yup': ^1.0.11 - '@fontsource/marck-script': ^4.5.11 - '@sentry/browser': ^7.48.0 - '@sentry/tracing': ^7.48.0 - '@simplewebauthn/browser': ^7.2.0 - '@sveltejs/adapter-auto': ^2.0.0 - '@sveltejs/adapter-node': ^1.2.3 - '@sveltejs/kit': ^1.15.7 - '@tailwindcss/typography': ^0.5.9 - '@types/canvas-confetti': ^1.6.0 - '@types/cookie': ^0.5.1 - '@types/dompurify': ^3.0.2 - '@types/js-cookie': ^3.0.3 - '@types/luxon': ^3.3.0 - '@types/marked': ^4.3.0 - '@types/qrcode': ^1.5.0 - '@types/sortablejs': ^1.15.1 - '@types/ua-parser-js': ^0.7.36 - '@typescript-eslint/eslint-plugin': ^5.59.0 - '@typescript-eslint/parser': ^5.59.0 - '@uppy/compressor': ^1.0.2 - '@uppy/core': ^3.2.0 - '@uppy/dashboard': ^3.4.0 - '@uppy/drag-drop': ^3.0.2 - '@uppy/drop-target': ^2.0.1 - '@uppy/image-editor': ^2.1.2 - '@uppy/progress-bar': ^3.0.2 - '@uppy/status-bar': ^3.1.1 - '@uppy/svelte': ^3.0.2 - '@uppy/xhr-upload': ^3.2.0 - autoprefixer: ^10.4.14 - canvas-confetti: ^1.6.0 - cookie: ^0.5.0 - crypto-js: ^4.1.1 - cssnano: ^6.0.0 - dompurify: ^3.0.3 - eslint: ^8.38.0 - eslint-config-prettier: ^8.8.0 - eslint-plugin-svelte3: ^4.0.0 - felte: ^1.2.7 - fuse.js: ^6.6.2 - highlight.js: ^11.7.0 - i18next: ^22.4.15 - i18next-browser-languagedetector: ^7.0.1 - js-cookie: ^3.0.1 - jws: ^4.0.0 - luxon: ^3.3.0 - mapbox-gl: ^2.14.1 - marked: ^5.0.0 - mdsvex: ^0.10.6 - minisearch: ^6.0.1 - pikaso: ^2.7.6 - plausible-tracker: ^0.3.8 - postcss: ^8.4.22 - postcss-import: ^15.1.0 - postcss-load-config: ^4.0.1 - prettier: ^2.8.7 - prettier-plugin-svelte: ^2.10.0 - qrcode: ^1.5.1 - sass: ^1.62.0 - socket.io-client: ^4.6.1 - svelte: ^3.58.0 - svelte-check: ^3.2.0 - svelte-preprocess: ^5.0.3 - svelte-range-slider-pips: ^2.1.1 - svelte-tippy: ^1.3.2 - swiper: ^8.4.7 - tailwindcss: ^3.3.1 - tippy.js: ^6.3.7 - tslib: ^2.5.0 - typescript: ~5.0.4 - ua-parser-js: ^1.0.35 - vite: ^4.2.2 - vite-plugin-iso-import: ^1.0.0 - yup: ^1.1.1 +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false dependencies: - i18next: 22.4.15 + i18next: + specifier: ^22.4.15 + version: 22.4.15 devDependencies: - '@beyonk/svelte-mapbox': 9.0.5_svelte@3.58.0 - '@ckeditor/ckeditor5-autoformat': 37.1.0 - '@ckeditor/ckeditor5-basic-styles': 37.1.0 - '@ckeditor/ckeditor5-build-balloon': 37.1.0 - '@ckeditor/ckeditor5-editor-balloon': 37.1.0 - '@ckeditor/ckeditor5-essentials': 37.1.0 - '@ckeditor/ckeditor5-theme-lark': 37.1.0 - '@felte/reporter-tippy': 1.1.5_tippy.js@6.3.7 - '@felte/validator-yup': 1.0.11_yup@1.1.1 - '@fontsource/marck-script': 4.5.11 - '@sentry/browser': 7.48.0 - '@sentry/tracing': 7.48.0 - '@simplewebauthn/browser': 7.2.0 - '@sveltejs/adapter-auto': 2.0.0_@sveltejs+kit@1.15.7 - '@sveltejs/adapter-node': 1.2.3_@sveltejs+kit@1.15.7 - '@sveltejs/kit': 1.15.7_svelte@3.58.0+vite@4.2.2 - '@tailwindcss/typography': 0.5.9_tailwindcss@3.3.1 - '@types/canvas-confetti': 1.6.0 - '@types/cookie': 0.5.1 - '@types/dompurify': 3.0.2 - '@types/js-cookie': 3.0.3 - '@types/luxon': 3.3.0 - '@types/marked': 4.3.0 - '@types/qrcode': 1.5.0 - '@types/sortablejs': 1.15.1 - '@types/ua-parser-js': 0.7.36 - '@typescript-eslint/eslint-plugin': 5.59.0_wsbkzerfphvgr4lle7vmeh64yi - '@typescript-eslint/parser': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - '@uppy/compressor': 1.0.2_@uppy+core@3.2.0 - '@uppy/core': 3.2.0 - '@uppy/dashboard': 3.4.0_@uppy+core@3.2.0 - '@uppy/drag-drop': 3.0.2_@uppy+core@3.2.0 - '@uppy/drop-target': 2.0.1_@uppy+core@3.2.0 - '@uppy/image-editor': 2.1.2_@uppy+core@3.2.0 - '@uppy/progress-bar': 3.0.2_@uppy+core@3.2.0 - '@uppy/status-bar': 3.1.1_@uppy+core@3.2.0 - '@uppy/svelte': 3.0.2_hte77j5zhiryjlw2fwlmsira6q - '@uppy/xhr-upload': 3.2.0_@uppy+core@3.2.0 - autoprefixer: 10.4.14_postcss@8.4.22 - canvas-confetti: 1.6.0 - cookie: 0.5.0 - crypto-js: 4.1.1 - cssnano: 6.0.0_postcss@8.4.22 - dompurify: 3.0.3 - eslint: 8.38.0 - eslint-config-prettier: 8.8.0_eslint@8.38.0 - eslint-plugin-svelte3: 4.0.0_a4ckjr7darsrglbip3svgxgxc4 - felte: 1.2.7_svelte@3.58.0 - fuse.js: 6.6.2 - highlight.js: 11.7.0 - i18next-browser-languagedetector: 7.0.1 - js-cookie: 3.0.1 - jws: 4.0.0 - luxon: 3.3.0 - mapbox-gl: 2.14.1 - marked: 5.0.0 - mdsvex: 0.10.6_svelte@3.58.0 - minisearch: 6.0.1 - pikaso: 2.7.6 - plausible-tracker: 0.3.8 - postcss: 8.4.22 - postcss-import: 15.1.0_postcss@8.4.22 - postcss-load-config: 4.0.1_postcss@8.4.22 - prettier: 2.8.7 - prettier-plugin-svelte: 2.10.0_ur5pqdgn24bclu6l6i7qojopk4 - qrcode: 1.5.1 - sass: 1.62.0 - socket.io-client: 4.6.1 - svelte: 3.58.0 - svelte-check: 3.2.0_hgmayuytslzk7fmzhfn6bohtwu - svelte-preprocess: 5.0.3_nrvzyekqy4pqqdxa53xkquyj6e - svelte-range-slider-pips: 2.1.1 - svelte-tippy: 1.3.2 - swiper: 8.4.7 - tailwindcss: 3.3.1_postcss@8.4.22 - tippy.js: 6.3.7 - tslib: 2.5.0 - typescript: 5.0.4 - ua-parser-js: 1.0.35 - vite: 4.2.2_sass@1.62.0 - vite-plugin-iso-import: 1.0.0_vite@4.2.2 - yup: 1.1.1 + '@beyonk/svelte-mapbox': + specifier: ^9.0.5 + version: 9.0.5(svelte@3.58.0) + '@ckeditor/ckeditor5-autoformat': + specifier: ^37.1.0 + version: 37.1.0 + '@ckeditor/ckeditor5-basic-styles': + specifier: ^37.1.0 + version: 37.1.0 + '@ckeditor/ckeditor5-build-balloon': + specifier: ^37.1.0 + version: 37.1.0 + '@ckeditor/ckeditor5-editor-balloon': + specifier: ^37.1.0 + version: 37.1.0 + '@ckeditor/ckeditor5-essentials': + specifier: ^37.1.0 + version: 37.1.0 + '@ckeditor/ckeditor5-theme-lark': + specifier: ^37.1.0 + version: 37.1.0 + '@felte/reporter-tippy': + specifier: ^1.1.5 + version: 1.1.5(tippy.js@6.3.7) + '@felte/validator-yup': + specifier: ^1.0.11 + version: 1.0.11(yup@1.1.1) + '@ffmpeg/core': + specifier: ^0.11.0 + version: 0.11.0 + '@ffmpeg/ffmpeg': + specifier: ^0.11.6 + version: 0.11.6 + '@fontsource/marck-script': + specifier: ^4.5.11 + version: 4.5.11 + '@sentry/browser': + specifier: ^7.48.0 + version: 7.48.0 + '@sentry/tracing': + specifier: ^7.48.0 + version: 7.48.0 + '@simplewebauthn/browser': + specifier: ^7.2.0 + version: 7.2.0 + '@sveltejs/adapter-auto': + specifier: ^2.0.0 + version: 2.0.0(@sveltejs/kit@1.15.7) + '@sveltejs/adapter-node': + specifier: ^1.2.3 + version: 1.2.3(@sveltejs/kit@1.15.7) + '@sveltejs/kit': + specifier: ^1.15.7 + version: 1.15.7(svelte@3.58.0)(vite@4.2.2) + '@tailwindcss/typography': + specifier: ^0.5.9 + version: 0.5.9(tailwindcss@3.3.1) + '@types/canvas-confetti': + specifier: ^1.6.0 + version: 1.6.0 + '@types/cookie': + specifier: ^0.5.1 + version: 0.5.1 + '@types/dompurify': + specifier: ^3.0.2 + version: 3.0.2 + '@types/js-cookie': + specifier: ^3.0.3 + version: 3.0.3 + '@types/luxon': + specifier: ^3.3.0 + version: 3.3.0 + '@types/marked': + specifier: ^4.3.0 + version: 4.3.0 + '@types/qrcode': + specifier: ^1.5.0 + version: 1.5.0 + '@types/sortablejs': + specifier: ^1.15.1 + version: 1.15.1 + '@types/ua-parser-js': + specifier: ^0.7.36 + version: 0.7.36 + '@typescript-eslint/eslint-plugin': + specifier: ^5.59.0 + version: 5.59.0(@typescript-eslint/parser@5.59.0)(eslint@8.38.0)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: ^5.59.0 + version: 5.59.0(eslint@8.38.0)(typescript@5.0.4) + '@unlazy/svelte': + specifier: ^0.8.9 + version: 0.8.9(fast-blurhash@1.1.2)(svelte@3.58.0)(thumbhash@0.1.1) + '@uppy/compressor': + specifier: ^1.0.2 + version: 1.0.2(@uppy/core@3.2.0) + '@uppy/core': + specifier: ^3.2.0 + version: 3.2.0 + '@uppy/dashboard': + specifier: ^3.4.0 + version: 3.4.0(@uppy/core@3.2.0) + '@uppy/drag-drop': + specifier: ^3.0.2 + version: 3.0.2(@uppy/core@3.2.0) + '@uppy/drop-target': + specifier: ^2.0.1 + version: 2.0.1(@uppy/core@3.2.0) + '@uppy/image-editor': + specifier: ^2.1.2 + version: 2.1.2(@uppy/core@3.2.0) + '@uppy/progress-bar': + specifier: ^3.0.2 + version: 3.0.2(@uppy/core@3.2.0) + '@uppy/status-bar': + specifier: ^3.1.1 + version: 3.1.1(@uppy/core@3.2.0) + '@uppy/svelte': + specifier: ^3.0.2 + version: 3.0.2(@uppy/core@3.2.0)(@uppy/dashboard@3.4.0)(@uppy/drag-drop@3.0.2)(@uppy/progress-bar@3.0.2)(@uppy/status-bar@3.1.1)(svelte@3.58.0) + '@uppy/xhr-upload': + specifier: ^3.2.0 + version: 3.2.0(@uppy/core@3.2.0) + autoprefixer: + specifier: ^10.4.14 + version: 10.4.14(postcss@8.4.22) + canvas-confetti: + specifier: ^1.6.0 + version: 1.6.0 + cookie: + specifier: ^0.5.0 + version: 0.5.0 + crypto-js: + specifier: ^4.1.1 + version: 4.1.1 + cssnano: + specifier: ^6.0.0 + version: 6.0.0(postcss@8.4.22) + dompurify: + specifier: ^3.0.3 + version: 3.0.3 + eslint: + specifier: ^8.38.0 + version: 8.38.0 + eslint-config-prettier: + specifier: ^8.8.0 + version: 8.8.0(eslint@8.38.0) + eslint-plugin-svelte3: + specifier: ^4.0.0 + version: 4.0.0(eslint@8.38.0)(svelte@3.58.0) + felte: + specifier: ^1.2.7 + version: 1.2.7(svelte@3.58.0) + fuse.js: + specifier: ^6.6.2 + version: 6.6.2 + highlight.js: + specifier: ^11.7.0 + version: 11.7.0 + i18next-browser-languagedetector: + specifier: ^7.0.1 + version: 7.0.1 + js-cookie: + specifier: ^3.0.1 + version: 3.0.1 + jws: + specifier: ^4.0.0 + version: 4.0.0 + luxon: + specifier: ^3.3.0 + version: 3.3.0 + mapbox-gl: + specifier: ^2.14.1 + version: 2.14.1 + marked: + specifier: ^5.0.0 + version: 5.0.0 + mdsvex: + specifier: ^0.10.6 + version: 0.10.6(svelte@3.58.0) + minisearch: + specifier: ^6.0.1 + version: 6.0.1 + pikaso: + specifier: ^2.7.6 + version: 2.7.6 + plausible-tracker: + specifier: ^0.3.8 + version: 0.3.8 + postcss: + specifier: ^8.4.22 + version: 8.4.22 + postcss-import: + specifier: ^15.1.0 + version: 15.1.0(postcss@8.4.22) + postcss-load-config: + specifier: ^4.0.1 + version: 4.0.1(postcss@8.4.22) + prettier: + specifier: ^2.8.7 + version: 2.8.7 + prettier-plugin-svelte: + specifier: ^2.10.0 + version: 2.10.0(prettier@2.8.7)(svelte@3.58.0) + qrcode: + specifier: ^1.5.1 + version: 1.5.1 + sass: + specifier: ^1.62.0 + version: 1.62.0 + socket.io-client: + specifier: ^4.6.1 + version: 4.6.1 + svelte: + specifier: ^3.58.0 + version: 3.58.0 + svelte-check: + specifier: ^3.2.0 + version: 3.2.0(postcss-load-config@4.0.1)(postcss@8.4.22)(sass@1.62.0)(svelte@3.58.0) + svelte-preprocess: + specifier: ^5.0.3 + version: 5.0.3(postcss-load-config@4.0.1)(postcss@8.4.22)(sass@1.62.0)(svelte@3.58.0)(typescript@5.0.4) + svelte-range-slider-pips: + specifier: ^2.1.1 + version: 2.1.1 + svelte-tippy: + specifier: ^1.3.2 + version: 1.3.2 + swiper: + specifier: ^8.4.7 + version: 8.4.7 + tailwindcss: + specifier: ^3.3.1 + version: 3.3.1(postcss@8.4.22) + thumbhash: + specifier: ^0.1.1 + version: 0.1.1 + tippy.js: + specifier: ^6.3.7 + version: 6.3.7 + tslib: + specifier: ^2.5.0 + version: 2.5.0 + typescript: + specifier: ~5.0.4 + version: 5.0.4 + ua-parser-js: + specifier: ^1.0.35 + version: 1.0.35 + vite: + specifier: ^4.2.2 + version: 4.2.2(sass@1.62.0) + vite-plugin-cross-origin-isolation: + specifier: ^0.1.6 + version: 0.1.6 + vite-plugin-iso-import: + specifier: ^1.0.0 + version: 1.0.0(vite@4.2.2) + yup: + specifier: ^1.1.1 + version: 1.1.1 packages: - /@babel/runtime/7.21.0: + /@babel/runtime@7.21.0: resolution: { integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== @@ -182,7 +282,7 @@ packages: dependencies: regenerator-runtime: 0.13.11 - /@beyonk/svelte-mapbox/9.0.5_svelte@3.58.0: + /@beyonk/svelte-mapbox@9.0.5(svelte@3.58.0): resolution: { integrity: sha512-PRuvVObqafFZ4rnqque0A0HuyPUrRwCjs1zxHJQdM4eG/1lPJpyEuEtcwuQuterAVldbcitr7un94irKg7SNpA== @@ -193,7 +293,7 @@ packages: svelte: 3.58.0 dev: true - /@ckeditor/ckeditor5-adapter-ckfinder/37.1.0: + /@ckeditor/ckeditor5-adapter-ckfinder@37.1.0: resolution: { integrity: sha512-SKjcsKqVw1EpZ3P0HaLDmPwf0Kv9qaqwUsp9Lv0InpPWlvubTCH4YwJ/bC7uh0NApQdygJ10S1CKn7/bSDrT4A== @@ -203,7 +303,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-autoformat/37.1.0: + /@ckeditor/ckeditor5-autoformat@37.1.0: resolution: { integrity: sha512-wZSuqsD6oz06fbE2zCn8PUDyax5YUDWFnB/26piLBu0HteRYFXJtIq6s2vA+zBbFfR3FL7362t+DP9VEHGigtw== @@ -213,7 +313,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-basic-styles/37.1.0: + /@ckeditor/ckeditor5-basic-styles@37.1.0: resolution: { integrity: sha512-AwCiVsq5Wh0tBOPLOV0NADnZRNw210h1/xTzsO2U8TGBcbVJ4ukU07OMSvkOhi7jrA4wLZI7R+XmhZR0vsUGkA== @@ -223,7 +323,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-block-quote/37.1.0: + /@ckeditor/ckeditor5-block-quote@37.1.0: resolution: { integrity: sha512-975XXg4YzJ857UF7dPujGxIkyvVfU6m4/QTCKU5j2SbrTqPKCQ59PLOOgyy1qC76D/uyqV1+V+beGairUrmA1A== @@ -233,7 +333,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-build-balloon/37.1.0: + /@ckeditor/ckeditor5-build-balloon@37.1.0: resolution: { integrity: sha512-aHvz2xgrm0IXsYrjtD84tvoFpGSiHL8oMaVOMrVrb+mRZdoMDnByq7dg9ViiSsWINWExQYFfeWoNyj8VKKIR6A== @@ -262,7 +362,7 @@ packages: '@ckeditor/ckeditor5-typing': 37.1.0 dev: true - /@ckeditor/ckeditor5-ckbox/37.1.0: + /@ckeditor/ckeditor5-ckbox@37.1.0: resolution: { integrity: sha512-XcbQPFkGevxKLilM28szORH/PZyR39cLwogZgothLXX4aPiiBGox8ldN6uI7cTaDkGjxzvaBF1AvHhcAPGs5pA== @@ -272,7 +372,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-ckfinder/37.1.0: + /@ckeditor/ckeditor5-ckfinder@37.1.0: resolution: { integrity: sha512-zgNldaJC9g3o0zy2plmIffO1SyPsBDVdVq65Y6zoT4YXqandpEwjdR/kGFwHBYr6hdMz4MsaPDXRXxYIAwU0LA== @@ -282,7 +382,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-clipboard/37.1.0: + /@ckeditor/ckeditor5-clipboard@37.1.0: resolution: { integrity: sha512-0L1driXKRl1IUZ9amo+DVBGJuNjuVQ4nmuurIDqR1U8pRFt34wBzaIHivUbsKeZYe74RC4m4tE2DcUrltXwLAQ== @@ -296,7 +396,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-cloud-services/37.1.0: + /@ckeditor/ckeditor5-cloud-services@37.1.0: resolution: { integrity: sha512-C5a+DKu1afASJVC0fl62WMjwaMIEulG/B2uyXySY6hXdHVC3aZkX0Z1Csn7QA2E0nk3KMkoGxCLWXJnsJk2gtg== @@ -306,7 +406,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-core/37.1.0: + /@ckeditor/ckeditor5-core@37.1.0: resolution: { integrity: sha512-edewiWlMCK5BPN9Can0A9skob9dNDMrv09khiKaUYK5PEobZZQSyUBck52vXpt255u2rnlmhF5phTqsQo5EiOw== @@ -318,7 +418,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-easy-image/37.1.0: + /@ckeditor/ckeditor5-easy-image@37.1.0: resolution: { integrity: sha512-1pu7IF0gpfIUVPci06kQaf76jvJkavFmbkK6MpxjccFsCVa2HONgyPfbMHvBLb2J5TBm/IeN+yHF/qmKiIMTKg== @@ -328,7 +428,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-editor-balloon/37.1.0: + /@ckeditor/ckeditor5-editor-balloon@37.1.0: resolution: { integrity: sha512-n2FktR7e2kS1nKJJS3NV2XcqDfY5LvGxrqu5Qkx+26TlSlIwr0Bs+apvlTqWWQw4maYHOb3JvKHNur4xBKl1eQ== @@ -339,7 +439,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-engine/37.1.0: + /@ckeditor/ckeditor5-engine@37.1.0: resolution: { integrity: sha512-D/xWNOgqk3G1qtv8P2UCmpHcIONjJE0NRJeJuJ8jppIgOYpbVG/7KSuzJYV7G1M9oGSBAeNb7U+lz7y/eg38Hw== @@ -350,7 +450,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-enter/37.1.0: + /@ckeditor/ckeditor5-enter@37.1.0: resolution: { integrity: sha512-m8e+yInNi4Hi5YWN0+Jj5ZFZjFvUi6VKPGsCSRyAmOiB3J9AO1/P4pYhhAXXpD7RzJQ0hmNiwZgRDZWeq/ZZNA== @@ -362,7 +462,7 @@ packages: '@ckeditor/ckeditor5-utils': 37.1.0 dev: true - /@ckeditor/ckeditor5-essentials/37.1.0: + /@ckeditor/ckeditor5-essentials@37.1.0: resolution: { integrity: sha512-LJl/3XHQpVvoFq22Z2JtNCog+0Z646MwEIZ70YyGyltA1fxXRpC0PrUg6NYND4AbDTHvWLUVTbQhhXzfSHw2KQ== @@ -372,7 +472,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-heading/37.1.0: + /@ckeditor/ckeditor5-heading@37.1.0: resolution: { integrity: sha512-fr2gOkiitJJKtJvunbitKEVwQoh26oBO7mbp/1BNSydtsOoP+B9Tl5S15WiPRAnc5pjIAT8MOJO5PQY/GDXs5Q== @@ -382,7 +482,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-image/37.1.0: + /@ckeditor/ckeditor5-image@37.1.0: resolution: { integrity: sha512-wIKGfasamPE7MWnIoNIpmWgxlZOz8bxw8ZaLucRdJGaU1+orzQabYcqZM+y+3puAowXs2MIGcA7kSmyJPvL0Jw== @@ -394,7 +494,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-indent/37.1.0: + /@ckeditor/ckeditor5-indent@37.1.0: resolution: { integrity: sha512-RBuyGV0um9l8dKwnugF0mfiL9H+AsaErhudcgfBhPFCoRQ3+vyQF3Mg14+iKdP2hybJQ6OaT+6a1P8OPzrq85Q== @@ -404,7 +504,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-link/37.1.0: + /@ckeditor/ckeditor5-link@37.1.0: resolution: { integrity: sha512-ImVcYYfz5oR/zqHGYdvgSvfHU/7ia/psAqjL+T/5OaqMRunALdUzdtuAsMkWGEH/oF8vKRsdGeWwsyrEvTF4XA== @@ -416,7 +516,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-list/37.1.0: + /@ckeditor/ckeditor5-list@37.1.0: resolution: { integrity: sha512-hV1fNhpMkivlVuwRx0TVSEzPgciQa14uV/lbnhCmjT33WDrh8hAcYFK+kJx+9dB1OzNtyTlsMA/DxUJPdNr9TA== @@ -427,7 +527,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-media-embed/37.1.0: + /@ckeditor/ckeditor5-media-embed@37.1.0: resolution: { integrity: sha512-FFErNy2M+32rFeI6z16J38T7VVsqk5TDWkLRVqZF/5/VOBZ/TGcAjamEYkWnuzSHakuwDUbCwT+H3JVSKNnZJA== @@ -438,7 +538,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-paragraph/37.1.0: + /@ckeditor/ckeditor5-paragraph@37.1.0: resolution: { integrity: sha512-64G9VU8xVYzJrOjngtw2Zg58mXTkf4fiBhR4lUT9yZNLpVJ/8DXtphGtuXEPrlfL4DVrthHUeNfEdQXA2DGGZQ== @@ -450,7 +550,7 @@ packages: '@ckeditor/ckeditor5-utils': 37.1.0 dev: true - /@ckeditor/ckeditor5-paste-from-office/37.1.0: + /@ckeditor/ckeditor5-paste-from-office@37.1.0: resolution: { integrity: sha512-4l+Wt6HCG1yraQhCfRegReWoviLkEzqPb/6QxoFiqOZkzUCmCCTgGTwL709fOg3sE5hxYd4tfPb9ARQuOkfmgQ== @@ -460,7 +560,7 @@ packages: ckeditor5: 37.1.0 dev: true - /@ckeditor/ckeditor5-select-all/37.1.0: + /@ckeditor/ckeditor5-select-all@37.1.0: resolution: { integrity: sha512-E5f+TQuOsrhxj/8b8/5Lhym7hF8upeL61hHJpViBhf047F2qLcRBs8SXSm9PO0xS0nzg+RxigmkiYWI5inm74g== @@ -472,7 +572,7 @@ packages: '@ckeditor/ckeditor5-utils': 37.1.0 dev: true - /@ckeditor/ckeditor5-table/37.1.0: + /@ckeditor/ckeditor5-table@37.1.0: resolution: { integrity: sha512-XXAGEZtpRz9Y0ZZtrDZCYy8jFLOVNnfgQIoSH+SJjSGyaR/DjlmLPXpSiO3R8Y8s7dRncBqK8Z0JEST7UwfdGg== @@ -483,7 +583,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-theme-lark/37.1.0: + /@ckeditor/ckeditor5-theme-lark@37.1.0: resolution: { integrity: sha512-BbiudXFoZeLFKNTx3H9Zbr4yLn696IfFnokflMsTJMCeEjT33RhbSNxTbr6m19bobBcs3wkJaSfh0/3L4daRzQ== @@ -493,7 +593,7 @@ packages: '@ckeditor/ckeditor5-ui': 37.1.0 dev: true - /@ckeditor/ckeditor5-typing/37.1.0: + /@ckeditor/ckeditor5-typing@37.1.0: resolution: { integrity: sha512-dloH29SGgDu3torPKC6TDkaYvD1ic80m8WCk9xXaOUXzIYf73m+F5TQ/QcfONxb0++Sj1Pq1IQuIpqBOn82aXA== @@ -506,7 +606,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-ui/37.1.0: + /@ckeditor/ckeditor5-ui@37.1.0: resolution: { integrity: sha512-7qpA8yS2cSDJsTh+uaxFuvfprxmw0Kd1UWDqrLNv23jUHt+25cT+46/7VLP3hPdS/bwkXWxIXV6nAlrw3gTIjQ== @@ -518,7 +618,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-undo/37.1.0: + /@ckeditor/ckeditor5-undo@37.1.0: resolution: { integrity: sha512-BJMmi4mXCIZj0lO4AVL8+Fzoj6+fXx3yZxUl0i68wf+ogf36pclyiHlunIV9EKRv8OW/eY3WezRI0O2mVcKzJA== @@ -530,7 +630,7 @@ packages: '@ckeditor/ckeditor5-ui': 37.1.0 dev: true - /@ckeditor/ckeditor5-upload/37.1.0: + /@ckeditor/ckeditor5-upload@37.1.0: resolution: { integrity: sha512-P0srTN1+gz8V4cOk+coY2HY7Gm8MkQAHPFEYCms1G1Kk7G32z4cyGWp9UqCPI0nX5GGM0qYd/Kd78BN/cNyJJw== @@ -542,7 +642,7 @@ packages: '@ckeditor/ckeditor5-utils': 37.1.0 dev: true - /@ckeditor/ckeditor5-utils/37.1.0: + /@ckeditor/ckeditor5-utils@37.1.0: resolution: { integrity: sha512-r4rSbzMy0WFSuP0IRd+yYUMjzb279eiICksOEiHViiqoKQ8RqcGDlh+zOaACkgw6xvLxj96C5MwG2wsZsGJqcA== @@ -552,7 +652,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-watchdog/37.1.0: + /@ckeditor/ckeditor5-watchdog@37.1.0: resolution: { integrity: sha512-0d4WU2BO5n0tNzJl9iamnrFK+XEaK7gVEMIXcduznbupfFGVYFdrOXfDTdW0Yr59kpKEG8JbaWOF3aILjBRRWA== @@ -562,7 +662,7 @@ packages: lodash-es: 4.17.21 dev: true - /@ckeditor/ckeditor5-widget/37.1.0: + /@ckeditor/ckeditor5-widget@37.1.0: resolution: { integrity: sha512-7tWZLQrokqU28SK/gFoLgGhNshesiCC2nD+MtYie3PyXZ0nVhFDzCQxq94A02G1IpHdDW4WFKSmp2ix2z9lMNQ== @@ -578,19 +678,7 @@ packages: lodash-es: 4.17.21 dev: true - /@esbuild/android-arm/0.17.17: - resolution: - { - integrity: sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg== - } - engines: { node: '>=12' } - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm64/0.17.17: + /@esbuild/android-arm64@0.17.17: resolution: { integrity: sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg== @@ -602,7 +690,19 @@ packages: dev: true optional: true - /@esbuild/android-x64/0.17.17: + /@esbuild/android-arm@0.17.17: + resolution: + { + integrity: sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg== + } + engines: { node: '>=12' } + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.17: resolution: { integrity: sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA== @@ -614,7 +714,7 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64/0.17.17: + /@esbuild/darwin-arm64@0.17.17: resolution: { integrity: sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ== @@ -626,7 +726,7 @@ packages: dev: true optional: true - /@esbuild/darwin-x64/0.17.17: + /@esbuild/darwin-x64@0.17.17: resolution: { integrity: sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg== @@ -638,7 +738,7 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64/0.17.17: + /@esbuild/freebsd-arm64@0.17.17: resolution: { integrity: sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA== @@ -650,7 +750,7 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64/0.17.17: + /@esbuild/freebsd-x64@0.17.17: resolution: { integrity: sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw== @@ -662,19 +762,7 @@ packages: dev: true optional: true - /@esbuild/linux-arm/0.17.17: - resolution: - { - integrity: sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg== - } - engines: { node: '>=12' } - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64/0.17.17: + /@esbuild/linux-arm64@0.17.17: resolution: { integrity: sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw== @@ -686,7 +774,19 @@ packages: dev: true optional: true - /@esbuild/linux-ia32/0.17.17: + /@esbuild/linux-arm@0.17.17: + resolution: + { + integrity: sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg== + } + engines: { node: '>=12' } + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.17: resolution: { integrity: sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q== @@ -698,7 +798,7 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.17.17: + /@esbuild/linux-loong64@0.17.17: resolution: { integrity: sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw== @@ -710,7 +810,7 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el/0.17.17: + /@esbuild/linux-mips64el@0.17.17: resolution: { integrity: sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A== @@ -722,7 +822,7 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64/0.17.17: + /@esbuild/linux-ppc64@0.17.17: resolution: { integrity: sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ== @@ -734,7 +834,7 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64/0.17.17: + /@esbuild/linux-riscv64@0.17.17: resolution: { integrity: sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA== @@ -746,7 +846,7 @@ packages: dev: true optional: true - /@esbuild/linux-s390x/0.17.17: + /@esbuild/linux-s390x@0.17.17: resolution: { integrity: sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ== @@ -758,7 +858,7 @@ packages: dev: true optional: true - /@esbuild/linux-x64/0.17.17: + /@esbuild/linux-x64@0.17.17: resolution: { integrity: sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg== @@ -770,7 +870,7 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64/0.17.17: + /@esbuild/netbsd-x64@0.17.17: resolution: { integrity: sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA== @@ -782,7 +882,7 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64/0.17.17: + /@esbuild/openbsd-x64@0.17.17: resolution: { integrity: sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA== @@ -794,7 +894,7 @@ packages: dev: true optional: true - /@esbuild/sunos-x64/0.17.17: + /@esbuild/sunos-x64@0.17.17: resolution: { integrity: sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q== @@ -806,7 +906,7 @@ packages: dev: true optional: true - /@esbuild/win32-arm64/0.17.17: + /@esbuild/win32-arm64@0.17.17: resolution: { integrity: sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q== @@ -818,7 +918,7 @@ packages: dev: true optional: true - /@esbuild/win32-ia32/0.17.17: + /@esbuild/win32-ia32@0.17.17: resolution: { integrity: sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ== @@ -830,7 +930,7 @@ packages: dev: true optional: true - /@esbuild/win32-x64/0.17.17: + /@esbuild/win32-x64@0.17.17: resolution: { integrity: sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg== @@ -842,7 +942,7 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils/4.4.0_eslint@8.38.0: + /@eslint-community/eslint-utils@4.4.0(eslint@8.38.0): resolution: { integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== @@ -855,7 +955,7 @@ packages: eslint-visitor-keys: 3.4.0 dev: true - /@eslint-community/regexpp/4.5.0: + /@eslint-community/regexpp@4.5.0: resolution: { integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ== @@ -863,7 +963,7 @@ packages: engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } dev: true - /@eslint/eslintrc/2.0.2: + /@eslint/eslintrc@2.0.2: resolution: { integrity: sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ== @@ -883,7 +983,7 @@ packages: - supports-color dev: true - /@eslint/js/8.38.0: + /@eslint/js@8.38.0: resolution: { integrity: sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g== @@ -891,7 +991,7 @@ packages: engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dev: true - /@felte/common/1.1.4: + /@felte/common@1.1.4: resolution: { integrity: sha512-4jNB4EwRpaGZppwV/YqbGF7SVRwehWw+hyTGmw2N+pL86LuqVTTSrgVOGXwPaLTju1BxAptcoAXjxZbBf0XB4Q== @@ -899,7 +999,7 @@ packages: engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: true - /@felte/core/1.3.7: + /@felte/core@1.3.7: resolution: { integrity: sha512-/AkIEZu/Yg/K+YEdnup5c3Bb0xyr9ONdZnS0us6V/b9DgfiEqbcm1xgglD/mtwh+IH7KOhIuQecjBdPQfpNViQ== @@ -909,7 +1009,7 @@ packages: '@felte/common': 1.1.4 dev: true - /@felte/reporter-tippy/1.1.5_tippy.js@6.3.7: + /@felte/reporter-tippy@1.1.5(tippy.js@6.3.7): resolution: { integrity: sha512-boCEXGOkqTXRQa1l0t2Whjw/7wJHy16fA1Q3TNNj7XOiDAKYyzGfwbQn0kMR1jdzJTpSteB/xGb+ue1PenRDEQ== @@ -922,7 +1022,7 @@ packages: tippy.js: 6.3.7 dev: true - /@felte/validator-yup/1.0.11_yup@1.1.1: + /@felte/validator-yup@1.0.11(yup@1.1.1): resolution: { integrity: sha512-T3VQQtNGGSnnL2+IIeW+eQHqDmSphDzJA0Ho8ivhEWisWyaLlBn2RHx1Iiv9f6um10MFanbh+bxRNdQLr5TXdg== @@ -935,14 +1035,36 @@ packages: yup: 1.1.1 dev: true - /@fontsource/marck-script/4.5.11: + /@ffmpeg/core@0.11.0: + resolution: + { + integrity: sha512-9Tt/+2PMpkGPXUK8n6He9G8Y+qR6qmCPSCw9iEKZxHHOvJ9BE/r0Fccj+YgDZTlyu6rXxc9x6EqCaFBIt7qzjA== + } + dev: true + + /@ffmpeg/ffmpeg@0.11.6: + resolution: + { + integrity: sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA== + } + engines: { node: '>=12.16.1' } + dependencies: + is-url: 1.2.4 + node-fetch: 2.6.11 + regenerator-runtime: 0.13.11 + resolve-url: 0.2.1 + transitivePeerDependencies: + - encoding + dev: true + + /@fontsource/marck-script@4.5.11: resolution: { integrity: sha512-vFgTyId75aTZta/Qmbf+OaMavB83X4tNizLqul7/rWfb2PSJNL4O2jv8s8wNXT+NPIg0Z8eTcAobnThd38HbOQ== } dev: true - /@humanwhocodes/config-array/0.11.8: + /@humanwhocodes/config-array@0.11.8: resolution: { integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== @@ -956,7 +1078,7 @@ packages: - supports-color dev: true - /@humanwhocodes/module-importer/1.0.1: + /@humanwhocodes/module-importer@1.0.1: resolution: { integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== @@ -964,14 +1086,14 @@ packages: engines: { node: '>=12.22' } dev: true - /@humanwhocodes/object-schema/1.2.1: + /@humanwhocodes/object-schema@1.2.1: resolution: { integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== } dev: true - /@jridgewell/gen-mapping/0.3.3: + /@jridgewell/gen-mapping@0.3.3: resolution: { integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== @@ -983,7 +1105,7 @@ packages: '@jridgewell/trace-mapping': 0.3.18 dev: true - /@jridgewell/resolve-uri/3.1.0: + /@jridgewell/resolve-uri@3.1.0: resolution: { integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -991,7 +1113,7 @@ packages: engines: { node: '>=6.0.0' } dev: true - /@jridgewell/set-array/1.1.2: + /@jridgewell/set-array@1.1.2: resolution: { integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== @@ -999,21 +1121,21 @@ packages: engines: { node: '>=6.0.0' } dev: true - /@jridgewell/sourcemap-codec/1.4.14: + /@jridgewell/sourcemap-codec@1.4.14: resolution: { integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== } dev: true - /@jridgewell/sourcemap-codec/1.4.15: + /@jridgewell/sourcemap-codec@1.4.15: resolution: { integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== } dev: true - /@jridgewell/trace-mapping/0.3.18: + /@jridgewell/trace-mapping@0.3.18: resolution: { integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -1023,7 +1145,7 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@mapbox/geojson-rewind/0.5.2: + /@mapbox/geojson-rewind@0.5.2: resolution: { integrity: sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA== @@ -1034,7 +1156,7 @@ packages: minimist: 1.2.8 dev: true - /@mapbox/jsonlint-lines-primitives/2.0.2: + /@mapbox/jsonlint-lines-primitives@2.0.2: resolution: { integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ== @@ -1042,35 +1164,35 @@ packages: engines: { node: '>= 0.6' } dev: true - /@mapbox/mapbox-gl-supported/2.0.1: + /@mapbox/mapbox-gl-supported@2.0.1: resolution: { integrity: sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ== } dev: true - /@mapbox/point-geometry/0.1.0: + /@mapbox/point-geometry@0.1.0: resolution: { integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ== } dev: true - /@mapbox/tiny-sdf/2.0.6: + /@mapbox/tiny-sdf@2.0.6: resolution: { integrity: sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA== } dev: true - /@mapbox/unitbezier/0.0.1: + /@mapbox/unitbezier@0.0.1: resolution: { integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw== } dev: true - /@mapbox/vector-tile/1.3.1: + /@mapbox/vector-tile@1.3.1: resolution: { integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw== @@ -1079,7 +1201,7 @@ packages: '@mapbox/point-geometry': 0.1.0 dev: true - /@mapbox/whoots-js/3.1.0: + /@mapbox/whoots-js@3.1.0: resolution: { integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== @@ -1087,7 +1209,7 @@ packages: engines: { node: '>=6.0.0' } dev: true - /@nodelib/fs.scandir/2.1.5: + /@nodelib/fs.scandir@2.1.5: resolution: { integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== @@ -1098,7 +1220,7 @@ packages: run-parallel: 1.2.0 dev: true - /@nodelib/fs.stat/2.0.5: + /@nodelib/fs.stat@2.0.5: resolution: { integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1106,7 +1228,7 @@ packages: engines: { node: '>= 8' } dev: true - /@nodelib/fs.walk/1.2.8: + /@nodelib/fs.walk@1.2.8: resolution: { integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1117,21 +1239,21 @@ packages: fastq: 1.15.0 dev: true - /@polka/url/1.0.0-next.21: + /@polka/url@1.0.0-next.21: resolution: { integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== } dev: true - /@popperjs/core/2.11.7: + /@popperjs/core@2.11.7: resolution: { integrity: sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== } dev: true - /@rollup/plugin-commonjs/24.1.0_rollup@3.20.6: + /@rollup/plugin-commonjs@24.1.0(rollup@3.20.6): resolution: { integrity: sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ== @@ -1143,7 +1265,7 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.6 + '@rollup/pluginutils': 5.0.2(rollup@3.20.6) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 @@ -1152,7 +1274,7 @@ packages: rollup: 3.20.6 dev: true - /@rollup/plugin-json/6.0.0_rollup@3.20.6: + /@rollup/plugin-json@6.0.0(rollup@3.20.6): resolution: { integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w== @@ -1164,11 +1286,11 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.6 + '@rollup/pluginutils': 5.0.2(rollup@3.20.6) rollup: 3.20.6 dev: true - /@rollup/plugin-node-resolve/15.0.2_rollup@3.20.6: + /@rollup/plugin-node-resolve@15.0.2(rollup@3.20.6): resolution: { integrity: sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg== @@ -1180,7 +1302,7 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.6 + '@rollup/pluginutils': 5.0.2(rollup@3.20.6) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-builtin-module: 3.2.1 @@ -1189,7 +1311,7 @@ packages: rollup: 3.20.6 dev: true - /@rollup/pluginutils/5.0.2_rollup@3.20.6: + /@rollup/pluginutils@5.0.2(rollup@3.20.6): resolution: { integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== @@ -1207,7 +1329,7 @@ packages: rollup: 3.20.6 dev: true - /@sentry-internal/tracing/7.48.0: + /@sentry-internal/tracing@7.48.0: resolution: { integrity: sha512-MFAPDTrvCtfSm0/Zbmx7HA0Q5uCfRadOUpN8Y8rP1ndz+329h2kA3mZRCuC+3/aXL11zs2CHUhcAkGjwH2vogg== @@ -1220,7 +1342,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/browser/7.48.0: + /@sentry/browser@7.48.0: resolution: { integrity: sha512-tdx/2nhuiykncmXFlV4Dpp+Hxgt/v31LiyXE79IcM560wc+QmWKtzoW9azBWQ0xt5KOO3ERMib9qPE4/ql1/EQ== @@ -1235,7 +1357,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/core/7.48.0: + /@sentry/core@7.48.0: resolution: { integrity: sha512-8FYuJTMpyuxRZvlen3gQ3rpOtVInSDmSyXqWEhCLuG/w34AtWoTiW7G516rsAAh6Hy1TP91GooMWbonP3XQNTQ== @@ -1247,7 +1369,7 @@ packages: tslib: 1.14.1 dev: true - /@sentry/replay/7.48.0: + /@sentry/replay@7.48.0: resolution: { integrity: sha512-8fRHMGJ0NJeIZi6UucxUTvfDPaBa7+jU1kCTLjCcuH3X/UVz5PtGLMtFSO5U8HP+mUDlPs97MP1uoDvMa4S2Ng== @@ -1259,7 +1381,7 @@ packages: '@sentry/utils': 7.48.0 dev: true - /@sentry/tracing/7.48.0: + /@sentry/tracing@7.48.0: resolution: { integrity: sha512-X6w74Av0fyayNicKIlwL1IdpZ3O0ETQjyYXCDTwHoJL71ojrgrL5vdiNz8WwbPONTnqu98HehPYL/z3DCCKVbw== @@ -1269,7 +1391,7 @@ packages: '@sentry-internal/tracing': 7.48.0 dev: true - /@sentry/types/7.48.0: + /@sentry/types@7.48.0: resolution: { integrity: sha512-kkAszZwQ5/v4n7Yyw/DPNRWx7h724mVNRGZIJa9ggUMvTgMe7UKCZZ5wfQmYiKVlGbwd9pxXAcP8Oq15EbByFQ== @@ -1277,7 +1399,7 @@ packages: engines: { node: '>=8' } dev: true - /@sentry/utils/7.48.0: + /@sentry/utils@7.48.0: resolution: { integrity: sha512-d977sghkFVMfld0LrEyyY2gYrfayLPdDEpUDT+hg5y79r7zZDCFyHtdB86699E5K89MwDZahW7Erk+a1nk4x5w== @@ -1288,7 +1410,7 @@ packages: tslib: 1.14.1 dev: true - /@simplewebauthn/browser/7.2.0: + /@simplewebauthn/browser@7.2.0: resolution: { integrity: sha512-HHIvRPpqKy0UV/BsGAmx4rQRZuZTUFYLLH65FwpSOslqHruiHx3Ql/bq7A75bjWuJ296a+4BIAq3+SPaII01TQ== @@ -1297,21 +1419,21 @@ packages: '@simplewebauthn/typescript-types': 7.0.0 dev: true - /@simplewebauthn/typescript-types/7.0.0: + /@simplewebauthn/typescript-types@7.0.0: resolution: { integrity: sha512-bV+xACCFTsrLR/23ozHO06ZllHZaxC8LlI5YCo79GvU2BrN+rePDU2yXwZIYndNWcMQwRdndRdAhpafOh9AC/g== } dev: true - /@socket.io/component-emitter/3.1.0: + /@socket.io/component-emitter@3.1.0: resolution: { integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== } dev: true - /@sveltejs/adapter-auto/2.0.0_@sveltejs+kit@1.15.7: + /@sveltejs/adapter-auto@2.0.0(@sveltejs/kit@1.15.7): resolution: { integrity: sha512-b+gkHFZgD771kgV3aO4avHFd7y1zhmMYy9i6xOK7m/rwmwaRO8gnF5zBc0Rgca80B2PMU1bKNxyBTHA14OzUAQ== @@ -1319,11 +1441,11 @@ packages: peerDependencies: '@sveltejs/kit': ^1.0.0 dependencies: - '@sveltejs/kit': 1.15.7_svelte@3.58.0+vite@4.2.2 + '@sveltejs/kit': 1.15.7(svelte@3.58.0)(vite@4.2.2) import-meta-resolve: 2.2.2 dev: true - /@sveltejs/adapter-node/1.2.3_@sveltejs+kit@1.15.7: + /@sveltejs/adapter-node@1.2.3(@sveltejs/kit@1.15.7): resolution: { integrity: sha512-Fv6NyVpVWYA63KRaV6dDjcU8ytcWFiUr0siJOoHl+oWy5WHNEuRiJOUdiZzYbZo8MmvFaCoxHkTgPrVQhpqaRA== @@ -1331,14 +1453,14 @@ packages: peerDependencies: '@sveltejs/kit': ^1.0.0 dependencies: - '@rollup/plugin-commonjs': 24.1.0_rollup@3.20.6 - '@rollup/plugin-json': 6.0.0_rollup@3.20.6 - '@rollup/plugin-node-resolve': 15.0.2_rollup@3.20.6 - '@sveltejs/kit': 1.15.7_svelte@3.58.0+vite@4.2.2 + '@rollup/plugin-commonjs': 24.1.0(rollup@3.20.6) + '@rollup/plugin-json': 6.0.0(rollup@3.20.6) + '@rollup/plugin-node-resolve': 15.0.2(rollup@3.20.6) + '@sveltejs/kit': 1.15.7(svelte@3.58.0)(vite@4.2.2) rollup: 3.20.6 dev: true - /@sveltejs/kit/1.15.7_svelte@3.58.0+vite@4.2.2: + /@sveltejs/kit@1.15.7(svelte@3.58.0)(vite@4.2.2): resolution: { integrity: sha512-dgdKExsMJ16X3q8tEcuDlv+QIWAlJcf7IqCU2HWV13nmtTzwSA2n4VtEx9Gy5OGhH0SUAGNIupmlf0TdFSMXbw== @@ -1350,7 +1472,7 @@ packages: svelte: ^3.54.0 vite: ^4.0.0 dependencies: - '@sveltejs/vite-plugin-svelte': 2.0.4_svelte@3.58.0+vite@4.2.2 + '@sveltejs/vite-plugin-svelte': 2.0.4(svelte@3.58.0)(vite@4.2.2) '@types/cookie': 0.5.1 cookie: 0.5.0 devalue: 4.3.0 @@ -1364,12 +1486,12 @@ packages: svelte: 3.58.0 tiny-glob: 0.2.9 undici: 5.20.0 - vite: 4.2.2_sass@1.62.0 + vite: 4.2.2(sass@1.62.0) transitivePeerDependencies: - supports-color dev: true - /@sveltejs/vite-plugin-svelte/2.0.4_svelte@3.58.0+vite@4.2.2: + /@sveltejs/vite-plugin-svelte@2.0.4(svelte@3.58.0)(vite@4.2.2): resolution: { integrity: sha512-pjqhW00KwK2uzDGEr+yJBwut+D+4XfJO/+bHHdHzPRXn9+1Jeq5JcFHyrUiYaXgHtyhX0RsllCTm4ssAx4ZY7Q== @@ -1384,14 +1506,14 @@ packages: kleur: 4.1.5 magic-string: 0.30.0 svelte: 3.58.0 - svelte-hmr: 0.15.1_svelte@3.58.0 - vite: 4.2.2_sass@1.62.0 - vitefu: 0.2.4_vite@4.2.2 + svelte-hmr: 0.15.1(svelte@3.58.0) + vite: 4.2.2(sass@1.62.0) + vitefu: 0.2.4(vite@4.2.2) transitivePeerDependencies: - supports-color dev: true - /@tailwindcss/typography/0.5.9_tailwindcss@3.3.1: + /@tailwindcss/typography@0.5.9(tailwindcss@3.3.1): resolution: { integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg== @@ -1403,24 +1525,24 @@ packages: lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.10 - tailwindcss: 3.3.1_postcss@8.4.22 + tailwindcss: 3.3.1(postcss@8.4.22) dev: true - /@transloadit/prettier-bytes/0.0.7: + /@transloadit/prettier-bytes@0.0.7: resolution: { integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA== } dev: true - /@transloadit/prettier-bytes/0.0.9: + /@transloadit/prettier-bytes@0.0.9: resolution: { integrity: sha512-pCvdmea/F3Tn4hAtHqNXmjcixSaroJJ+L3STXlYJdir1g1m2mRQpWbN8a4SvgQtaw2930Ckhdx8qXdXBFMKbAA== } dev: true - /@trysound/sax/0.2.0: + /@trysound/sax@0.2.0: resolution: { integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== @@ -1428,21 +1550,21 @@ packages: engines: { node: '>=10.13.0' } dev: true - /@types/canvas-confetti/1.6.0: + /@types/canvas-confetti@1.6.0: resolution: { integrity: sha512-Yq6rIccwcco0TLD5SMUrIM7Fk7Fe/C0jmNRxJJCLtAF6gebDkPuUjK5EHedxecm69Pi/aA+It39Ux4OHmFhjRw== } dev: true - /@types/cookie/0.5.1: + /@types/cookie@0.5.1: resolution: { integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g== } dev: true - /@types/dompurify/3.0.2: + /@types/dompurify@3.0.2: resolution: { integrity: sha512-YBL4ziFebbbfQfH5mlC+QTJsvh0oJUrWbmxKMyEdL7emlHJqGR2Qb34TEFKj+VCayBvjKy3xczMFNhugThUsfQ== @@ -1451,56 +1573,56 @@ packages: '@types/trusted-types': 2.0.3 dev: true - /@types/estree/1.0.1: + /@types/estree@1.0.1: resolution: { integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== } dev: true - /@types/js-cookie/3.0.3: + /@types/js-cookie@3.0.3: resolution: { integrity: sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww== } dev: true - /@types/json-schema/7.0.11: + /@types/json-schema@7.0.11: resolution: { integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== } dev: true - /@types/luxon/3.3.0: + /@types/luxon@3.3.0: resolution: { integrity: sha512-uKRI5QORDnrGFYgcdAVnHvEIvEZ8noTpP/Bg+HeUzZghwinDlIS87DEenV5r1YoOF9G4x600YsUXLWZ19rmTmg== } dev: true - /@types/marked/4.3.0: + /@types/marked@4.3.0: resolution: { integrity: sha512-zK4gSFMjgslsv5Lyvr3O1yCjgmnE4pr8jbG8qVn4QglMwtpvPCf4YT2Wma7Nk95OxUUJI8Z+kzdXohbM7mVpGw== } dev: true - /@types/node/18.15.11: + /@types/node@18.15.11: resolution: { integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== } dev: true - /@types/pug/2.0.6: + /@types/pug@2.0.6: resolution: { integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg== } dev: true - /@types/qrcode/1.5.0: + /@types/qrcode@1.5.0: resolution: { integrity: sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA== @@ -1509,49 +1631,49 @@ packages: '@types/node': 18.15.11 dev: true - /@types/resolve/1.20.2: + /@types/resolve@1.20.2: resolution: { integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== } dev: true - /@types/semver/7.3.13: + /@types/semver@7.3.13: resolution: { integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== } dev: true - /@types/sortablejs/1.15.1: + /@types/sortablejs@1.15.1: resolution: { integrity: sha512-g/JwBNToh6oCTAwNS8UGVmjO7NLDKsejVhvE4x1eWiPTC3uCuNsa/TD4ssvX3du+MLiM+SHPNDuijp8y76JzLQ== } dev: true - /@types/trusted-types/2.0.3: + /@types/trusted-types@2.0.3: resolution: { integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== } dev: true - /@types/ua-parser-js/0.7.36: + /@types/ua-parser-js@0.7.36: resolution: { integrity: sha512-N1rW+njavs70y2cApeIw1vLMYXRwfBy+7trgavGuuTfOd7j1Yh7QTRc/yqsPl6ncokt72ZXuxEU0PiCp9bSwNQ== } dev: true - /@types/unist/2.0.6: + /@types/unist@2.0.6: resolution: { integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== } dev: true - /@typescript-eslint/eslint-plugin/5.59.0_wsbkzerfphvgr4lle7vmeh64yi: + /@typescript-eslint/eslint-plugin@5.59.0(@typescript-eslint/parser@5.59.0)(eslint@8.38.0)(typescript@5.0.4): resolution: { integrity: sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw== @@ -1566,23 +1688,23 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy + '@typescript-eslint/parser': 5.59.0(eslint@8.38.0)(typescript@5.0.4) '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/type-utils': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - '@typescript-eslint/utils': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy + '@typescript-eslint/type-utils': 5.59.0(eslint@8.38.0)(typescript@5.0.4) + '@typescript-eslint/utils': 5.59.0(eslint@8.38.0)(typescript@5.0.4) debug: 4.3.4 eslint: 8.38.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 semver: 7.5.0 - tsutils: 3.21.0_typescript@5.0.4 + tsutils: 3.21.0(typescript@5.0.4) typescript: 5.0.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/5.59.0_voubu7prgxjfsfbgx5d4sqnwiy: + /@typescript-eslint/parser@5.59.0(eslint@8.38.0)(typescript@5.0.4): resolution: { integrity: sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w== @@ -1597,7 +1719,7 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.59.0 '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/typescript-estree': 5.59.0_typescript@5.0.4 + '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.0.4) debug: 4.3.4 eslint: 8.38.0 typescript: 5.0.4 @@ -1605,7 +1727,7 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager/5.59.0: + /@typescript-eslint/scope-manager@5.59.0: resolution: { integrity: sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ== @@ -1616,7 +1738,7 @@ packages: '@typescript-eslint/visitor-keys': 5.59.0 dev: true - /@typescript-eslint/type-utils/5.59.0_voubu7prgxjfsfbgx5d4sqnwiy: + /@typescript-eslint/type-utils@5.59.0(eslint@8.38.0)(typescript@5.0.4): resolution: { integrity: sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA== @@ -1629,17 +1751,17 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.59.0_typescript@5.0.4 - '@typescript-eslint/utils': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy + '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.0.4) + '@typescript-eslint/utils': 5.59.0(eslint@8.38.0)(typescript@5.0.4) debug: 4.3.4 eslint: 8.38.0 - tsutils: 3.21.0_typescript@5.0.4 + tsutils: 3.21.0(typescript@5.0.4) typescript: 5.0.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.59.0: + /@typescript-eslint/types@5.59.0: resolution: { integrity: sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA== @@ -1647,7 +1769,7 @@ packages: engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dev: true - /@typescript-eslint/typescript-estree/5.59.0_typescript@5.0.4: + /@typescript-eslint/typescript-estree@5.59.0(typescript@5.0.4): resolution: { integrity: sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg== @@ -1665,13 +1787,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.0 - tsutils: 3.21.0_typescript@5.0.4 + tsutils: 3.21.0(typescript@5.0.4) typescript: 5.0.4 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.59.0_voubu7prgxjfsfbgx5d4sqnwiy: + /@typescript-eslint/utils@5.59.0(eslint@8.38.0)(typescript@5.0.4): resolution: { integrity: sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA== @@ -1680,12 +1802,12 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.38.0) '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 '@typescript-eslint/scope-manager': 5.59.0 '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/typescript-estree': 5.59.0_typescript@5.0.4 + '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.0.4) eslint: 8.38.0 eslint-scope: 5.1.1 semver: 7.5.0 @@ -1694,7 +1816,7 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.59.0: + /@typescript-eslint/visitor-keys@5.59.0: resolution: { integrity: sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA== @@ -1705,7 +1827,32 @@ packages: eslint-visitor-keys: 3.4.0 dev: true - /@uppy/companion-client/3.1.3: + /@unlazy/core@0.8.9: + resolution: + { + integrity: sha512-DQ4WB/cuEWTknU/59uRwpSipvMAJzBDmRyaHDUc1RcXi0Z7/Vcl0EE7BpROxEynqd1EI+2oMWQaDLyXffUdUiA== + } + dependencies: + fast-blurhash: 1.1.2 + thumbhash: 0.1.1 + dev: true + + /@unlazy/svelte@0.8.9(fast-blurhash@1.1.2)(svelte@3.58.0)(thumbhash@0.1.1): + resolution: + { + integrity: sha512-vgOYuOlknE6l/QhzZzpncsU8dMaTgLKGd7Xn4qwqTWAa3TF+6NRL7QedPJb2XBY8Th7yRQ79ZqeXaSDxWtL9zA== + } + peerDependencies: + svelte: ^3.54.0 + dependencies: + svelte: 3.58.0 + unlazy: 0.8.9(fast-blurhash@1.1.2)(thumbhash@0.1.1) + transitivePeerDependencies: + - fast-blurhash + - thumbhash + dev: true + + /@uppy/companion-client@3.1.3: resolution: { integrity: sha512-l70qOd4P9PSqxPDOFD1LMusDGGi36LCCiQko/e+Uw5hBtzN9vhAG5rQm242FlNoFdxK5T6jmfoZJSVel0UTvzg== @@ -1715,7 +1862,7 @@ packages: namespace-emitter: 2.0.1 dev: true - /@uppy/compressor/1.0.2_@uppy+core@3.2.0: + /@uppy/compressor@1.0.2(@uppy/core@3.2.0): resolution: { integrity: sha512-Z8G7UrfOkceBaz+vxmOjJwYBJ5Gf6MImsoAvMJvhKyQlPCaonyvglAtkkITinIWbD9jCf7At9PUIiBHJZAATaw== @@ -1731,7 +1878,7 @@ packages: promise-queue: 2.2.5 dev: true - /@uppy/core/3.2.0: + /@uppy/core@3.2.0: resolution: { integrity: sha512-w/jdNCIdmxt4uPt4UBPfzmQ7HanIE73GiKKeHtZo6Gp+HWOsUhY7DBimGUk3IsX/vMJTSB2+RhZAUOBGRaP5fA== @@ -1747,7 +1894,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/dashboard/3.4.0_@uppy+core@3.2.0: + /@uppy/dashboard@3.4.0(@uppy/core@3.2.0): resolution: { integrity: sha512-4zns7+C3didR8AKUa4T8+0dg7TWTpeMsUjqhBNWYdxGptcG+m5+zMr+olCLA2Tjou41x75j4BqtPLrEGTr1yVA== @@ -1757,10 +1904,10 @@ packages: dependencies: '@transloadit/prettier-bytes': 0.0.7 '@uppy/core': 3.2.0 - '@uppy/informer': 3.0.2_@uppy+core@3.2.0 - '@uppy/provider-views': 3.3.0_@uppy+core@3.2.0 - '@uppy/status-bar': 3.1.1_@uppy+core@3.2.0 - '@uppy/thumbnail-generator': 3.0.3_@uppy+core@3.2.0 + '@uppy/informer': 3.0.2(@uppy/core@3.2.0) + '@uppy/provider-views': 3.3.0(@uppy/core@3.2.0) + '@uppy/status-bar': 3.1.1(@uppy/core@3.2.0) + '@uppy/thumbnail-generator': 3.0.3(@uppy/core@3.2.0) '@uppy/utils': 5.3.0 classnames: 2.3.2 is-shallow-equal: 1.0.1 @@ -1770,7 +1917,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/drag-drop/3.0.2_@uppy+core@3.2.0: + /@uppy/drag-drop@3.0.2(@uppy/core@3.2.0): resolution: { integrity: sha512-zUOEYuUBtO1kfFbiwq24ZuDninu17IWkTTyV1covARm9YiZkrqG11n6VsTe/SQbXJxYh0kAttKIVP+QK1/n48g== @@ -1783,7 +1930,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/drop-target/2.0.1_@uppy+core@3.2.0: + /@uppy/drop-target@2.0.1(@uppy/core@3.2.0): resolution: { integrity: sha512-FMO8wj+0dx4mlwXKxFWSTUF+irgr0BVXadyc4qaoBBtZ3vEcwc3jP7SQfwk3JizV/D5MYG8MRICRbPAIrY9M8w== @@ -1795,7 +1942,7 @@ packages: '@uppy/utils': 5.3.0 dev: true - /@uppy/image-editor/2.1.2_@uppy+core@3.2.0: + /@uppy/image-editor@2.1.2(@uppy/core@3.2.0): resolution: { integrity: sha512-nWg9kFh+9OelYnY6fr1Hto2Fx6Fy1MyQAsCZAzy9umAQMkGrIs3Ql2iYDap4gm9IdiBI8ajzX57qTepLXbKPXg== @@ -1809,7 +1956,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/informer/3.0.2_@uppy+core@3.2.0: + /@uppy/informer@3.0.2(@uppy/core@3.2.0): resolution: { integrity: sha512-WPOEZCxAaw9JBhkneIW3bm6SqceUtZGxDT++3SlwKUyn4kr0p808LrCVITooUkyqrd0lOn9TAFKFNjinUxbCGw== @@ -1822,7 +1969,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/progress-bar/3.0.2_@uppy+core@3.2.0: + /@uppy/progress-bar@3.0.2(@uppy/core@3.2.0): resolution: { integrity: sha512-vVV+mvPfe4AbTajDAkZo64u15/epgFAMAt0FFs1SX+U8GzwA5Ry+MQ6Tagn1mN+POkql6OZS4F3Dv2Y5pKusBg== @@ -1835,7 +1982,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/provider-views/3.3.0_@uppy+core@3.2.0: + /@uppy/provider-views@3.3.0(@uppy/core@3.2.0): resolution: { integrity: sha512-J2yhALNzsEAtR9NDN5ZJ1Poy/SaTIg9gdZfKCaD4G7+xaKnnbb8E9ca5YjVNbOJnW0LNazggNvpJu0D6SeNgHg== @@ -1851,7 +1998,7 @@ packages: preact: 10.13.2 dev: true - /@uppy/status-bar/3.1.1_@uppy+core@3.2.0: + /@uppy/status-bar@3.1.1(@uppy/core@3.2.0): resolution: { integrity: sha512-2YjUu/1T4aCHXrvRkuqKIVvdt+j7EjcUfP6B3YQ645U9Wokzv+3lm2c9xoVm/J3M6S/iDtkgki4Wj+fjKyUSEA== @@ -1867,14 +2014,14 @@ packages: preact: 10.13.2 dev: true - /@uppy/store-default/3.0.3: + /@uppy/store-default@3.0.3: resolution: { integrity: sha512-/zlvQNj4HjkthI+7dNdj/8mOlTg1Zb1gJ/ZsOxof0g3xXD+OAwm7asRnOwpfj2dos+lExdW/zMn8XsRGsuvb6Q== } dev: true - /@uppy/svelte/3.0.2_hte77j5zhiryjlw2fwlmsira6q: + /@uppy/svelte@3.0.2(@uppy/core@3.2.0)(@uppy/dashboard@3.4.0)(@uppy/drag-drop@3.0.2)(@uppy/progress-bar@3.0.2)(@uppy/status-bar@3.1.1)(svelte@3.58.0): resolution: { integrity: sha512-WGcZQMfWIg9Fv3cz1qgNiGnytUbU/CUk7tOq9GW/vIpn67xTnbOxxAqEFnHDwS16UL1pjDkr5GarijDihm21yg== @@ -1888,14 +2035,14 @@ packages: svelte: ^3.0.0 dependencies: '@uppy/core': 3.2.0 - '@uppy/dashboard': 3.4.0_@uppy+core@3.2.0 - '@uppy/drag-drop': 3.0.2_@uppy+core@3.2.0 - '@uppy/progress-bar': 3.0.2_@uppy+core@3.2.0 - '@uppy/status-bar': 3.1.1_@uppy+core@3.2.0 + '@uppy/dashboard': 3.4.0(@uppy/core@3.2.0) + '@uppy/drag-drop': 3.0.2(@uppy/core@3.2.0) + '@uppy/progress-bar': 3.0.2(@uppy/core@3.2.0) + '@uppy/status-bar': 3.1.1(@uppy/core@3.2.0) svelte: 3.58.0 dev: true - /@uppy/thumbnail-generator/3.0.3_@uppy+core@3.2.0: + /@uppy/thumbnail-generator@3.0.3(@uppy/core@3.2.0): resolution: { integrity: sha512-tiTNqHU/Co8HQ2ag88JZv6KMV1/dbOLbtpI0QJBKOdnPtcDtzQbT8LM69EW9JRrqSAxaoLPrr/VccXvv8BIe2A== @@ -1908,7 +2055,7 @@ packages: exifr: 7.1.3 dev: true - /@uppy/utils/5.3.0: + /@uppy/utils@5.3.0: resolution: { integrity: sha512-tPW+HtRkjanFQAa/XD2e6kjJ7ZeMHtVxEVeBeRtKTnltsCA9kNF2gDwxtUVPEWyLrKzW+CvRm60NDiOKaWUuww== @@ -1917,7 +2064,7 @@ packages: lodash.throttle: 4.1.1 dev: true - /@uppy/xhr-upload/3.2.0_@uppy+core@3.2.0: + /@uppy/xhr-upload@3.2.0(@uppy/core@3.2.0): resolution: { integrity: sha512-iMz9xUEslgvfdAXb+R2R6n+bYPpAPOtI5dnYAKo4f8rsxB0KmuPSzaLO1GW2v+Gx3Qz3ghiIhWlTeHZ6zwLtoQ== @@ -1931,7 +2078,7 @@ packages: nanoid: 4.0.2 dev: true - /acorn-jsx/5.3.2_acorn@8.8.2: + /acorn-jsx@5.3.2(acorn@8.8.2): resolution: { integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1942,7 +2089,7 @@ packages: acorn: 8.8.2 dev: true - /acorn/8.8.2: + /acorn@8.8.2: resolution: { integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== @@ -1951,7 +2098,7 @@ packages: hasBin: true dev: true - /ajv/6.12.6: + /ajv@6.12.6: resolution: { integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1963,7 +2110,7 @@ packages: uri-js: 4.4.1 dev: true - /ansi-regex/5.0.1: + /ansi-regex@5.0.1: resolution: { integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== @@ -1971,7 +2118,7 @@ packages: engines: { node: '>=8' } dev: true - /ansi-styles/4.3.0: + /ansi-styles@4.3.0: resolution: { integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -1981,14 +2128,14 @@ packages: color-convert: 2.0.1 dev: true - /any-promise/1.3.0: + /any-promise@1.3.0: resolution: { integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== } dev: true - /anymatch/3.1.3: + /anymatch@3.1.3: resolution: { integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -1999,21 +2146,21 @@ packages: picomatch: 2.3.1 dev: true - /arg/5.0.2: + /arg@5.0.2: resolution: { integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== } dev: true - /argparse/2.0.1: + /argparse@2.0.1: resolution: { integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== } dev: true - /array-union/2.1.0: + /array-union@2.1.0: resolution: { integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== @@ -2021,7 +2168,7 @@ packages: engines: { node: '>=8' } dev: true - /autoprefixer/10.4.14_postcss@8.4.22: + /autoprefixer@10.4.14(postcss@8.4.22): resolution: { integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== @@ -2040,14 +2187,14 @@ packages: postcss-value-parser: 4.2.0 dev: true - /balanced-match/1.0.2: + /balanced-match@1.0.2: resolution: { integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== } dev: true - /binary-extensions/2.2.0: + /binary-extensions@2.2.0: resolution: { integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== @@ -2055,21 +2202,21 @@ packages: engines: { node: '>=8' } dev: true - /blueimp-canvas-to-blob/3.29.0: + /blueimp-canvas-to-blob@3.29.0: resolution: { integrity: sha512-0pcSSGxC0QxT+yVkivxIqW0Y4VlO2XSDPofBAqoJ1qJxgH9eiUDLv50Rixij2cDuEfx4M6DpD9UGZpRhT5Q8qg== } dev: true - /boolbase/1.0.0: + /boolbase@1.0.0: resolution: { integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== } dev: true - /brace-expansion/1.1.11: + /brace-expansion@1.1.11: resolution: { integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== @@ -2079,7 +2226,7 @@ packages: concat-map: 0.0.1 dev: true - /brace-expansion/2.0.1: + /brace-expansion@2.0.1: resolution: { integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== @@ -2088,7 +2235,7 @@ packages: balanced-match: 1.0.2 dev: true - /braces/3.0.2: + /braces@3.0.2: resolution: { integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -2098,7 +2245,7 @@ packages: fill-range: 7.0.1 dev: true - /browserslist/4.21.5: + /browserslist@4.21.5: resolution: { integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== @@ -2109,24 +2256,24 @@ packages: caniuse-lite: 1.0.30001480 electron-to-chromium: 1.4.368 node-releases: 2.0.10 - update-browserslist-db: 1.0.11_browserslist@4.21.5 + update-browserslist-db: 1.0.11(browserslist@4.21.5) dev: true - /buffer-crc32/0.2.13: + /buffer-crc32@0.2.13: resolution: { integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== } dev: true - /buffer-equal-constant-time/1.0.1: + /buffer-equal-constant-time@1.0.1: resolution: { integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== } dev: true - /builtin-modules/3.3.0: + /builtin-modules@3.3.0: resolution: { integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== @@ -2134,7 +2281,7 @@ packages: engines: { node: '>=6' } dev: true - /busboy/1.6.0: + /busboy@1.6.0: resolution: { integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== @@ -2144,7 +2291,7 @@ packages: streamsearch: 1.1.0 dev: true - /callsites/3.1.0: + /callsites@3.1.0: resolution: { integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -2152,7 +2299,7 @@ packages: engines: { node: '>=6' } dev: true - /camelcase-css/2.0.1: + /camelcase-css@2.0.1: resolution: { integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== @@ -2160,7 +2307,7 @@ packages: engines: { node: '>= 6' } dev: true - /camelcase/5.3.1: + /camelcase@5.3.1: resolution: { integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== @@ -2168,7 +2315,7 @@ packages: engines: { node: '>=6' } dev: true - /caniuse-api/3.0.0: + /caniuse-api@3.0.0: resolution: { integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== @@ -2180,21 +2327,21 @@ packages: lodash.uniq: 4.5.0 dev: true - /caniuse-lite/1.0.30001480: + /caniuse-lite@1.0.30001480: resolution: { integrity: sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ== } dev: true - /canvas-confetti/1.6.0: + /canvas-confetti@1.6.0: resolution: { integrity: sha512-ej+w/m8Jzpv9Z7W7uJZer14Ke8P2ogsjg4ZMGIuq4iqUOqY2Jq8BNW42iGmNfRwREaaEfFIczLuZZiEVSYNHAA== } dev: true - /chalk/4.1.2: + /chalk@4.1.2: resolution: { integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2205,7 +2352,7 @@ packages: supports-color: 7.2.0 dev: true - /chokidar/3.5.3: + /chokidar@3.5.3: resolution: { integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -2223,7 +2370,7 @@ packages: fsevents: 2.3.2 dev: true - /ckeditor5/37.1.0: + /ckeditor5@37.1.0: resolution: { integrity: sha512-sT/w0+pZ/p8ANrNaFI+LtUYRSUECFC1lvhQqGczGWEYD+pdYQTQxYVDy8QEYE5V9E5I7uvt4Dbcq9w6TjlLC/w== @@ -2245,14 +2392,14 @@ packages: '@ckeditor/ckeditor5-widget': 37.1.0 dev: true - /classnames/2.3.2: + /classnames@2.3.2: resolution: { integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== } dev: true - /cliui/6.0.0: + /cliui@6.0.0: resolution: { integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== @@ -2263,7 +2410,7 @@ packages: wrap-ansi: 6.2.0 dev: true - /color-convert/2.0.1: + /color-convert@2.0.1: resolution: { integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== @@ -2273,21 +2420,21 @@ packages: color-name: 1.1.4 dev: true - /color-name/1.1.4: + /color-name@1.1.4: resolution: { integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== } dev: true - /colord/2.9.3: + /colord@2.9.3: resolution: { integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== } dev: true - /commander/4.1.1: + /commander@4.1.1: resolution: { integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== @@ -2295,7 +2442,7 @@ packages: engines: { node: '>= 6' } dev: true - /commander/7.2.0: + /commander@7.2.0: resolution: { integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -2303,14 +2450,14 @@ packages: engines: { node: '>= 10' } dev: true - /commondir/1.0.1: + /commondir@1.0.1: resolution: { integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== } dev: true - /compressorjs/1.2.1: + /compressorjs@1.2.1: resolution: { integrity: sha512-+geIjeRnPhQ+LLvvA7wxBQE5ddeLU7pJ3FsKFWirDw6veY3s9iLxAQEw7lXGHnhCJvBujEQWuNnGzZcvCvdkLQ== @@ -2320,14 +2467,14 @@ packages: is-blob: 2.1.0 dev: true - /concat-map/0.0.1: + /concat-map@0.0.1: resolution: { integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== } dev: true - /cookie/0.5.0: + /cookie@0.5.0: resolution: { integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== @@ -2335,14 +2482,14 @@ packages: engines: { node: '>= 0.6' } dev: true - /cropperjs/1.5.7: + /cropperjs@1.5.7: resolution: { integrity: sha512-sGj+G/ofKh+f6A4BtXLJwtcKJgMUsXYVUubfTo9grERiDGXncttefmue/fyQFvn8wfdyoD1KhDRYLfjkJFl0yw== } dev: true - /cross-spawn/7.0.3: + /cross-spawn@7.0.3: resolution: { integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2354,14 +2501,14 @@ packages: which: 2.0.2 dev: true - /crypto-js/4.1.1: + /crypto-js@4.1.1: resolution: { integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== } dev: true - /css-declaration-sorter/6.4.0_postcss@8.4.22: + /css-declaration-sorter@6.4.0(postcss@8.4.22): resolution: { integrity: sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew== @@ -2373,7 +2520,7 @@ packages: postcss: 8.4.22 dev: true - /css-select/5.1.0: + /css-select@5.1.0: resolution: { integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== @@ -2386,7 +2533,7 @@ packages: nth-check: 2.1.1 dev: true - /css-tree/2.2.1: + /css-tree@2.2.1: resolution: { integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== @@ -2397,7 +2544,7 @@ packages: source-map-js: 1.0.2 dev: true - /css-tree/2.3.1: + /css-tree@2.3.1: resolution: { integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== @@ -2408,7 +2555,7 @@ packages: source-map-js: 1.0.2 dev: true - /css-what/6.1.0: + /css-what@6.1.0: resolution: { integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== @@ -2416,14 +2563,14 @@ packages: engines: { node: '>= 6' } dev: true - /csscolorparser/1.0.3: + /csscolorparser@1.0.3: resolution: { integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w== } dev: true - /cssesc/3.0.0: + /cssesc@3.0.0: resolution: { integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== @@ -2432,7 +2579,7 @@ packages: hasBin: true dev: true - /cssnano-preset-default/6.0.0_postcss@8.4.22: + /cssnano-preset-default@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-BDxlaFzObRDXUiCCBQUNQcI+f1/aX2mgoNtXGjV6PG64POcHoDUoX+LgMWw+Q4609QhxwkcSnS65YFs42RA6qQ== @@ -2441,39 +2588,39 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - css-declaration-sorter: 6.4.0_postcss@8.4.22 - cssnano-utils: 4.0.0_postcss@8.4.22 + css-declaration-sorter: 6.4.0(postcss@8.4.22) + cssnano-utils: 4.0.0(postcss@8.4.22) postcss: 8.4.22 - postcss-calc: 8.2.4_postcss@8.4.22 - postcss-colormin: 6.0.0_postcss@8.4.22 - postcss-convert-values: 6.0.0_postcss@8.4.22 - postcss-discard-comments: 6.0.0_postcss@8.4.22 - postcss-discard-duplicates: 6.0.0_postcss@8.4.22 - postcss-discard-empty: 6.0.0_postcss@8.4.22 - postcss-discard-overridden: 6.0.0_postcss@8.4.22 - postcss-merge-longhand: 6.0.0_postcss@8.4.22 - postcss-merge-rules: 6.0.0_postcss@8.4.22 - postcss-minify-font-values: 6.0.0_postcss@8.4.22 - postcss-minify-gradients: 6.0.0_postcss@8.4.22 - postcss-minify-params: 6.0.0_postcss@8.4.22 - postcss-minify-selectors: 6.0.0_postcss@8.4.22 - postcss-normalize-charset: 6.0.0_postcss@8.4.22 - postcss-normalize-display-values: 6.0.0_postcss@8.4.22 - postcss-normalize-positions: 6.0.0_postcss@8.4.22 - postcss-normalize-repeat-style: 6.0.0_postcss@8.4.22 - postcss-normalize-string: 6.0.0_postcss@8.4.22 - postcss-normalize-timing-functions: 6.0.0_postcss@8.4.22 - postcss-normalize-unicode: 6.0.0_postcss@8.4.22 - postcss-normalize-url: 6.0.0_postcss@8.4.22 - postcss-normalize-whitespace: 6.0.0_postcss@8.4.22 - postcss-ordered-values: 6.0.0_postcss@8.4.22 - postcss-reduce-initial: 6.0.0_postcss@8.4.22 - postcss-reduce-transforms: 6.0.0_postcss@8.4.22 - postcss-svgo: 6.0.0_postcss@8.4.22 - postcss-unique-selectors: 6.0.0_postcss@8.4.22 + postcss-calc: 8.2.4(postcss@8.4.22) + postcss-colormin: 6.0.0(postcss@8.4.22) + postcss-convert-values: 6.0.0(postcss@8.4.22) + postcss-discard-comments: 6.0.0(postcss@8.4.22) + postcss-discard-duplicates: 6.0.0(postcss@8.4.22) + postcss-discard-empty: 6.0.0(postcss@8.4.22) + postcss-discard-overridden: 6.0.0(postcss@8.4.22) + postcss-merge-longhand: 6.0.0(postcss@8.4.22) + postcss-merge-rules: 6.0.0(postcss@8.4.22) + postcss-minify-font-values: 6.0.0(postcss@8.4.22) + postcss-minify-gradients: 6.0.0(postcss@8.4.22) + postcss-minify-params: 6.0.0(postcss@8.4.22) + postcss-minify-selectors: 6.0.0(postcss@8.4.22) + postcss-normalize-charset: 6.0.0(postcss@8.4.22) + postcss-normalize-display-values: 6.0.0(postcss@8.4.22) + postcss-normalize-positions: 6.0.0(postcss@8.4.22) + postcss-normalize-repeat-style: 6.0.0(postcss@8.4.22) + postcss-normalize-string: 6.0.0(postcss@8.4.22) + postcss-normalize-timing-functions: 6.0.0(postcss@8.4.22) + postcss-normalize-unicode: 6.0.0(postcss@8.4.22) + postcss-normalize-url: 6.0.0(postcss@8.4.22) + postcss-normalize-whitespace: 6.0.0(postcss@8.4.22) + postcss-ordered-values: 6.0.0(postcss@8.4.22) + postcss-reduce-initial: 6.0.0(postcss@8.4.22) + postcss-reduce-transforms: 6.0.0(postcss@8.4.22) + postcss-svgo: 6.0.0(postcss@8.4.22) + postcss-unique-selectors: 6.0.0(postcss@8.4.22) dev: true - /cssnano-utils/4.0.0_postcss@8.4.22: + /cssnano-utils@4.0.0(postcss@8.4.22): resolution: { integrity: sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw== @@ -2485,7 +2632,7 @@ packages: postcss: 8.4.22 dev: true - /cssnano/6.0.0_postcss@8.4.22: + /cssnano@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-RGlcbzGhzEBCHuQe3k+Udyj5M00z0pm9S+VurHXFEOXxH+y0sVrJH2sMzoyz2d8N1EScazg+DVvmgyx0lurwwA== @@ -2494,12 +2641,12 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - cssnano-preset-default: 6.0.0_postcss@8.4.22 + cssnano-preset-default: 6.0.0(postcss@8.4.22) lilconfig: 2.1.0 postcss: 8.4.22 dev: true - /csso/5.0.5: + /csso@5.0.5: resolution: { integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== @@ -2509,7 +2656,7 @@ packages: css-tree: 2.2.1 dev: true - /debug/4.3.4: + /debug@4.3.4: resolution: { integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -2524,7 +2671,7 @@ packages: ms: 2.1.2 dev: true - /decamelize/1.2.0: + /decamelize@1.2.0: resolution: { integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== @@ -2532,14 +2679,14 @@ packages: engines: { node: '>=0.10.0' } dev: true - /deep-is/0.1.4: + /deep-is@0.1.4: resolution: { integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== } dev: true - /deepmerge/4.3.1: + /deepmerge@4.3.1: resolution: { integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== @@ -2547,7 +2694,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /detect-indent/6.1.0: + /detect-indent@6.1.0: resolution: { integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== @@ -2555,28 +2702,28 @@ packages: engines: { node: '>=8' } dev: true - /devalue/4.3.0: + /devalue@4.3.0: resolution: { integrity: sha512-n94yQo4LI3w7erwf84mhRUkUJfhLoCZiLyoOZ/QFsDbcWNZePrLwbQpvZBUG2TNxwV3VjCKPxkiiQA6pe3TrTA== } dev: true - /didyoumean/1.2.2: + /didyoumean@1.2.2: resolution: { integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== } dev: true - /dijkstrajs/1.0.3: + /dijkstrajs@1.0.3: resolution: { integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA== } dev: true - /dir-glob/3.0.1: + /dir-glob@3.0.1: resolution: { integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== @@ -2586,14 +2733,14 @@ packages: path-type: 4.0.0 dev: true - /dlv/1.1.3: + /dlv@1.1.3: resolution: { integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== } dev: true - /doctrine/3.0.0: + /doctrine@3.0.0: resolution: { integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== @@ -2603,7 +2750,7 @@ packages: esutils: 2.0.3 dev: true - /dom-serializer/2.0.0: + /dom-serializer@2.0.0: resolution: { integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== @@ -2614,7 +2761,7 @@ packages: entities: 4.5.0 dev: true - /dom7/4.0.6: + /dom7@4.0.6: resolution: { integrity: sha512-emjdpPLhpNubapLFdjNL9tP06Sr+GZkrIHEXLWvOGsytACUrkbeIdjO5g77m00BrHTznnlcNqgmn7pCN192TBA== @@ -2623,14 +2770,14 @@ packages: ssr-window: 4.0.2 dev: true - /domelementtype/2.3.0: + /domelementtype@2.3.0: resolution: { integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== } dev: true - /domhandler/5.0.3: + /domhandler@5.0.3: resolution: { integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== @@ -2640,14 +2787,14 @@ packages: domelementtype: 2.3.0 dev: true - /dompurify/3.0.3: + /dompurify@3.0.3: resolution: { integrity: sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ== } dev: true - /domutils/3.0.1: + /domutils@3.0.1: resolution: { integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== @@ -2658,14 +2805,14 @@ packages: domhandler: 5.0.3 dev: true - /earcut/2.2.4: + /earcut@2.2.4: resolution: { integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ== } dev: true - /ecdsa-sig-formatter/1.0.11: + /ecdsa-sig-formatter@1.0.11: resolution: { integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== @@ -2674,28 +2821,28 @@ packages: safe-buffer: 5.2.1 dev: true - /electron-to-chromium/1.4.368: + /electron-to-chromium@1.4.368: resolution: { integrity: sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw== } dev: true - /emoji-regex/8.0.0: + /emoji-regex@8.0.0: resolution: { integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== } dev: true - /encode-utf8/1.0.3: + /encode-utf8@1.0.3: resolution: { integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== } dev: true - /engine.io-client/6.4.0: + /engine.io-client@6.4.0: resolution: { integrity: sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g== @@ -2712,7 +2859,7 @@ packages: - utf-8-validate dev: true - /engine.io-parser/5.0.6: + /engine.io-parser@5.0.6: resolution: { integrity: sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw== @@ -2720,7 +2867,7 @@ packages: engines: { node: '>=10.0.0' } dev: true - /entities/4.5.0: + /entities@4.5.0: resolution: { integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== @@ -2728,21 +2875,21 @@ packages: engines: { node: '>=0.12' } dev: true - /es-module-lexer/1.2.1: + /es-module-lexer@1.2.1: resolution: { integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg== } dev: true - /es6-promise/3.3.1: + /es6-promise@3.3.1: resolution: { integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg== } dev: true - /esbuild/0.17.17: + /esbuild@0.17.17: resolution: { integrity: sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA== @@ -2775,7 +2922,7 @@ packages: '@esbuild/win32-x64': 0.17.17 dev: true - /escalade/3.1.1: + /escalade@3.1.1: resolution: { integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== @@ -2783,7 +2930,7 @@ packages: engines: { node: '>=6' } dev: true - /escape-string-regexp/4.0.0: + /escape-string-regexp@4.0.0: resolution: { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== @@ -2791,7 +2938,7 @@ packages: engines: { node: '>=10' } dev: true - /eslint-config-prettier/8.8.0_eslint@8.38.0: + /eslint-config-prettier@8.8.0(eslint@8.38.0): resolution: { integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== @@ -2803,7 +2950,7 @@ packages: eslint: 8.38.0 dev: true - /eslint-plugin-svelte3/4.0.0_a4ckjr7darsrglbip3svgxgxc4: + /eslint-plugin-svelte3@4.0.0(eslint@8.38.0)(svelte@3.58.0): resolution: { integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g== @@ -2816,7 +2963,7 @@ packages: svelte: 3.58.0 dev: true - /eslint-scope/5.1.1: + /eslint-scope@5.1.1: resolution: { integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -2827,7 +2974,7 @@ packages: estraverse: 4.3.0 dev: true - /eslint-scope/7.2.0: + /eslint-scope@7.2.0: resolution: { integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== @@ -2838,7 +2985,7 @@ packages: estraverse: 5.3.0 dev: true - /eslint-visitor-keys/3.4.0: + /eslint-visitor-keys@3.4.0: resolution: { integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== @@ -2846,7 +2993,7 @@ packages: engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dev: true - /eslint/8.38.0: + /eslint@8.38.0: resolution: { integrity: sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg== @@ -2854,7 +3001,7 @@ packages: engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.38.0) '@eslint-community/regexpp': 4.5.0 '@eslint/eslintrc': 2.0.2 '@eslint/js': 8.38.0 @@ -2898,14 +3045,14 @@ packages: - supports-color dev: true - /esm-env/1.0.0: + /esm-env@1.0.0: resolution: { integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA== } dev: true - /espree/9.5.1: + /espree@9.5.1: resolution: { integrity: sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg== @@ -2913,11 +3060,11 @@ packages: engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } dependencies: acorn: 8.8.2 - acorn-jsx: 5.3.2_acorn@8.8.2 + acorn-jsx: 5.3.2(acorn@8.8.2) eslint-visitor-keys: 3.4.0 dev: true - /esquery/1.5.0: + /esquery@1.5.0: resolution: { integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== @@ -2927,7 +3074,7 @@ packages: estraverse: 5.3.0 dev: true - /esrecurse/4.3.0: + /esrecurse@4.3.0: resolution: { integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== @@ -2937,7 +3084,7 @@ packages: estraverse: 5.3.0 dev: true - /estraverse/4.3.0: + /estraverse@4.3.0: resolution: { integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -2945,7 +3092,7 @@ packages: engines: { node: '>=4.0' } dev: true - /estraverse/5.3.0: + /estraverse@5.3.0: resolution: { integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== @@ -2953,14 +3100,14 @@ packages: engines: { node: '>=4.0' } dev: true - /estree-walker/2.0.2: + /estree-walker@2.0.2: resolution: { integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== } dev: true - /esutils/2.0.3: + /esutils@2.0.3: resolution: { integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== @@ -2968,28 +3115,35 @@ packages: engines: { node: '>=0.10.0' } dev: true - /eventemitter3/4.0.7: + /eventemitter3@4.0.7: resolution: { integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== } dev: true - /exifr/7.1.3: + /exifr@7.1.3: resolution: { integrity: sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw== } dev: true - /fast-deep-equal/3.1.3: + /fast-blurhash@1.1.2: + resolution: + { + integrity: sha512-lJVOgYSlahqkRhrKumNx/SGB2F/qS0D1z7xjGYjb5EZJRtlzySGMniZjkQ9h9Rv8sPmM/V9orEgRiMwazDNH6A== + } + dev: true + + /fast-deep-equal@3.1.3: resolution: { integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== } dev: true - /fast-glob/3.2.12: + /fast-glob@3.2.12: resolution: { integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -3003,21 +3157,21 @@ packages: micromatch: 4.0.5 dev: true - /fast-json-stable-stringify/2.1.0: + /fast-json-stable-stringify@2.1.0: resolution: { integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== } dev: true - /fast-levenshtein/2.0.6: + /fast-levenshtein@2.0.6: resolution: { integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== } dev: true - /fastq/1.15.0: + /fastq@1.15.0: resolution: { integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== @@ -3026,7 +3180,7 @@ packages: reusify: 1.0.4 dev: true - /felte/1.2.7_svelte@3.58.0: + /felte@1.2.7(svelte@3.58.0): resolution: { integrity: sha512-VfCkYBODReCUrYeRMmJ9lRs7O/pC4PYKMTT7E2K6m9UzmTGpm3Ql3C518J3gUVVG5ZeEeSEifUaqmrAcaWB89w== @@ -3039,7 +3193,7 @@ packages: svelte: 3.58.0 dev: true - /file-entry-cache/6.0.1: + /file-entry-cache@6.0.1: resolution: { integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== @@ -3049,7 +3203,7 @@ packages: flat-cache: 3.0.4 dev: true - /fill-range/7.0.1: + /fill-range@7.0.1: resolution: { integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== @@ -3059,7 +3213,7 @@ packages: to-regex-range: 5.0.1 dev: true - /find-up/4.1.0: + /find-up@4.1.0: resolution: { integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3070,7 +3224,7 @@ packages: path-exists: 4.0.0 dev: true - /find-up/5.0.0: + /find-up@5.0.0: resolution: { integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -3081,7 +3235,7 @@ packages: path-exists: 4.0.0 dev: true - /flat-cache/3.0.4: + /flat-cache@3.0.4: resolution: { integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== @@ -3092,28 +3246,28 @@ packages: rimraf: 3.0.2 dev: true - /flatted/3.2.7: + /flatted@3.2.7: resolution: { integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== } dev: true - /fraction.js/4.2.0: + /fraction.js@4.2.0: resolution: { integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== } dev: true - /fs.realpath/1.0.0: + /fs.realpath@1.0.0: resolution: { integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== } dev: true - /fsevents/2.3.2: + /fsevents@2.3.2: resolution: { integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -3124,14 +3278,14 @@ packages: dev: true optional: true - /function-bind/1.1.1: + /function-bind@1.1.1: resolution: { integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== } dev: true - /fuse.js/6.6.2: + /fuse.js@6.6.2: resolution: { integrity: sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA== @@ -3139,14 +3293,14 @@ packages: engines: { node: '>=10' } dev: true - /geojson-vt/3.2.1: + /geojson-vt@3.2.1: resolution: { integrity: sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== } dev: true - /get-caller-file/2.0.5: + /get-caller-file@2.0.5: resolution: { integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -3154,7 +3308,7 @@ packages: engines: { node: 6.* || 8.* || >= 10.* } dev: true - /get-stream/6.0.1: + /get-stream@6.0.1: resolution: { integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -3162,14 +3316,14 @@ packages: engines: { node: '>=10' } dev: true - /gl-matrix/3.4.3: + /gl-matrix@3.4.3: resolution: { integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== } dev: true - /glob-parent/5.1.2: + /glob-parent@5.1.2: resolution: { integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -3179,7 +3333,7 @@ packages: is-glob: 4.0.3 dev: true - /glob-parent/6.0.2: + /glob-parent@6.0.2: resolution: { integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -3189,7 +3343,7 @@ packages: is-glob: 4.0.3 dev: true - /glob/7.1.6: + /glob@7.1.6: resolution: { integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -3203,7 +3357,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/7.2.3: + /glob@7.2.3: resolution: { integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -3217,7 +3371,7 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob/8.1.0: + /glob@8.1.0: resolution: { integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -3231,7 +3385,7 @@ packages: once: 1.4.0 dev: true - /globals/13.20.0: + /globals@13.20.0: resolution: { integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== @@ -3241,14 +3395,14 @@ packages: type-fest: 0.20.2 dev: true - /globalyzer/0.1.0: + /globalyzer@0.1.0: resolution: { integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== } dev: true - /globby/11.1.0: + /globby@11.1.0: resolution: { integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -3263,35 +3417,35 @@ packages: slash: 3.0.0 dev: true - /globrex/0.1.2: + /globrex@0.1.2: resolution: { integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== } dev: true - /graceful-fs/4.2.11: + /graceful-fs@4.2.11: resolution: { integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== } dev: true - /grapheme-splitter/1.0.4: + /grapheme-splitter@1.0.4: resolution: { integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== } dev: true - /grid-index/1.1.0: + /grid-index@1.1.0: resolution: { integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== } dev: true - /has-flag/4.0.0: + /has-flag@4.0.0: resolution: { integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== @@ -3299,7 +3453,7 @@ packages: engines: { node: '>=8' } dev: true - /has/1.0.3: + /has@1.0.3: resolution: { integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -3309,7 +3463,7 @@ packages: function-bind: 1.1.1 dev: true - /highlight.js/11.7.0: + /highlight.js@11.7.0: resolution: { integrity: sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ== @@ -3317,7 +3471,7 @@ packages: engines: { node: '>=12.0.0' } dev: true - /i18next-browser-languagedetector/7.0.1: + /i18next-browser-languagedetector@7.0.1: resolution: { integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g== @@ -3326,7 +3480,7 @@ packages: '@babel/runtime': 7.21.0 dev: true - /i18next/22.4.15: + /i18next@22.4.15: resolution: { integrity: sha512-yYudtbFrrmWKLEhl6jvKUYyYunj4bTBCe2qIUYAxbXoPusY7YmdwPvOE6fx6UIfWvmlbCWDItr7wIs8KEBZ5Zg== @@ -3335,14 +3489,14 @@ packages: '@babel/runtime': 7.21.0 dev: false - /ieee754/1.2.1: + /ieee754@1.2.1: resolution: { integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== } dev: true - /ignore/5.2.4: + /ignore@5.2.4: resolution: { integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -3350,14 +3504,14 @@ packages: engines: { node: '>= 4' } dev: true - /immutable/4.3.0: + /immutable@4.3.0: resolution: { integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== } dev: true - /import-fresh/3.3.0: + /import-fresh@3.3.0: resolution: { integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -3368,14 +3522,14 @@ packages: resolve-from: 4.0.0 dev: true - /import-meta-resolve/2.2.2: + /import-meta-resolve@2.2.2: resolution: { integrity: sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA== } dev: true - /imurmurhash/0.1.4: + /imurmurhash@0.1.4: resolution: { integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== @@ -3383,7 +3537,7 @@ packages: engines: { node: '>=0.8.19' } dev: true - /inflight/1.0.6: + /inflight@1.0.6: resolution: { integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== @@ -3393,14 +3547,14 @@ packages: wrappy: 1.0.2 dev: true - /inherits/2.0.4: + /inherits@2.0.4: resolution: { integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== } dev: true - /is-binary-path/2.1.0: + /is-binary-path@2.1.0: resolution: { integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== @@ -3410,7 +3564,7 @@ packages: binary-extensions: 2.2.0 dev: true - /is-blob/2.1.0: + /is-blob@2.1.0: resolution: { integrity: sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw== @@ -3418,7 +3572,7 @@ packages: engines: { node: '>=6' } dev: true - /is-builtin-module/3.2.1: + /is-builtin-module@3.2.1: resolution: { integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== @@ -3428,7 +3582,7 @@ packages: builtin-modules: 3.3.0 dev: true - /is-core-module/2.12.0: + /is-core-module@2.12.0: resolution: { integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== @@ -3437,7 +3591,7 @@ packages: has: 1.0.3 dev: true - /is-extglob/2.1.1: + /is-extglob@2.1.1: resolution: { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== @@ -3445,7 +3599,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /is-fullwidth-code-point/3.0.0: + /is-fullwidth-code-point@3.0.0: resolution: { integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== @@ -3453,7 +3607,7 @@ packages: engines: { node: '>=8' } dev: true - /is-glob/4.0.3: + /is-glob@4.0.3: resolution: { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -3463,14 +3617,14 @@ packages: is-extglob: 2.1.1 dev: true - /is-module/1.0.0: + /is-module@1.0.0: resolution: { integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== } dev: true - /is-number/7.0.0: + /is-number@7.0.0: resolution: { integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== @@ -3478,7 +3632,7 @@ packages: engines: { node: '>=0.12.0' } dev: true - /is-path-inside/3.0.3: + /is-path-inside@3.0.3: resolution: { integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -3486,7 +3640,7 @@ packages: engines: { node: '>=8' } dev: true - /is-reference/1.2.1: + /is-reference@1.2.1: resolution: { integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== @@ -3495,21 +3649,28 @@ packages: '@types/estree': 1.0.1 dev: true - /is-shallow-equal/1.0.1: + /is-shallow-equal@1.0.1: resolution: { integrity: sha512-lq5RvK+85Hs5J3p4oA4256M1FEffzmI533ikeDHvJd42nouRRx5wBzt36JuviiGe5dIPyHON/d0/Up+PBo6XkQ== } dev: true - /isexe/2.0.0: + /is-url@1.2.4: + resolution: + { + integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + } + dev: true + + /isexe@2.0.0: resolution: { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } dev: true - /jiti/1.18.2: + /jiti@1.18.2: resolution: { integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== @@ -3517,7 +3678,7 @@ packages: hasBin: true dev: true - /js-cookie/3.0.1: + /js-cookie@3.0.1: resolution: { integrity: sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw== @@ -3525,14 +3686,14 @@ packages: engines: { node: '>=12' } dev: true - /js-sdsl/4.4.0: + /js-sdsl@4.4.0: resolution: { integrity: sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== } dev: true - /js-yaml/4.1.0: + /js-yaml@4.1.0: resolution: { integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -3542,21 +3703,21 @@ packages: argparse: 2.0.1 dev: true - /json-schema-traverse/0.4.1: + /json-schema-traverse@0.4.1: resolution: { integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== } dev: true - /json-stable-stringify-without-jsonify/1.0.1: + /json-stable-stringify-without-jsonify@1.0.1: resolution: { integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== } dev: true - /jwa/2.0.0: + /jwa@2.0.0: resolution: { integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== @@ -3567,7 +3728,7 @@ packages: safe-buffer: 5.2.1 dev: true - /jws/4.0.0: + /jws@4.0.0: resolution: { integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== @@ -3577,14 +3738,14 @@ packages: safe-buffer: 5.2.1 dev: true - /kdbush/3.0.0: + /kdbush@3.0.0: resolution: { integrity: sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew== } dev: true - /kleur/4.1.5: + /kleur@4.1.5: resolution: { integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== @@ -3592,14 +3753,14 @@ packages: engines: { node: '>=6' } dev: true - /konva/8.4.3: + /konva@8.4.3: resolution: { integrity: sha512-ARqdgAbdNIougRlOKvkQwHlGhXPRBV4KvhCP+qoPpGoVQwwiJe4Hkdu4HHdRPb9rGUp04jDTAxBzEwBsE272pg== } dev: true - /levn/0.4.1: + /levn@0.4.1: resolution: { integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== @@ -3610,7 +3771,7 @@ packages: type-check: 0.4.0 dev: true - /lilconfig/2.1.0: + /lilconfig@2.1.0: resolution: { integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== @@ -3618,14 +3779,14 @@ packages: engines: { node: '>=10' } dev: true - /lines-and-columns/1.2.4: + /lines-and-columns@1.2.4: resolution: { integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== } dev: true - /locate-path/5.0.0: + /locate-path@5.0.0: resolution: { integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== @@ -3635,7 +3796,7 @@ packages: p-locate: 4.1.0 dev: true - /locate-path/6.0.0: + /locate-path@6.0.0: resolution: { integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== @@ -3645,63 +3806,63 @@ packages: p-locate: 5.0.0 dev: true - /lodash-es/4.17.21: + /lodash-es@4.17.21: resolution: { integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== } dev: true - /lodash.castarray/4.4.0: + /lodash.castarray@4.4.0: resolution: { integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== } dev: true - /lodash.debounce/4.0.8: + /lodash.debounce@4.0.8: resolution: { integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== } dev: true - /lodash.isplainobject/4.0.6: + /lodash.isplainobject@4.0.6: resolution: { integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== } dev: true - /lodash.memoize/4.1.2: + /lodash.memoize@4.1.2: resolution: { integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== } dev: true - /lodash.merge/4.6.2: + /lodash.merge@4.6.2: resolution: { integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== } dev: true - /lodash.throttle/4.1.1: + /lodash.throttle@4.1.1: resolution: { integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== } dev: true - /lodash.uniq/4.5.0: + /lodash.uniq@4.5.0: resolution: { integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== } dev: true - /lru-cache/6.0.0: + /lru-cache@6.0.0: resolution: { integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== @@ -3711,7 +3872,7 @@ packages: yallist: 4.0.0 dev: true - /luxon/3.3.0: + /luxon@3.3.0: resolution: { integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg== @@ -3719,7 +3880,7 @@ packages: engines: { node: '>=12' } dev: true - /magic-string/0.27.0: + /magic-string@0.27.0: resolution: { integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== @@ -3729,7 +3890,7 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /magic-string/0.30.0: + /magic-string@0.30.0: resolution: { integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ== @@ -3739,7 +3900,7 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /mapbox-gl/2.14.1: + /mapbox-gl@2.14.1: resolution: { integrity: sha512-KfHYcjzJeEF1UXZQin3vSdyIXoTBBdpNesTMmyzP9Dv8wRg8DnRu078Vr/CJ2A6Xocsvh9UAqTWYtHlrc20nwA== @@ -3768,7 +3929,7 @@ packages: vt-pbf: 3.1.3 dev: true - /marked/5.0.0: + /marked@5.0.0: resolution: { integrity: sha512-YQ6+L9l/NSBDjFgCQQebmTCc62EUdZ5RpIZ7A/FmC8IYMB5s7Cz8sT7imuMAkbIL4CvXpQLdW45fpK5UwiU7DA== @@ -3777,21 +3938,21 @@ packages: hasBin: true dev: true - /mdn-data/2.0.28: + /mdn-data@2.0.28: resolution: { integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== } dev: true - /mdn-data/2.0.30: + /mdn-data@2.0.30: resolution: { integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== } dev: true - /mdsvex/0.10.6_svelte@3.58.0: + /mdsvex@0.10.6(svelte@3.58.0): resolution: { integrity: sha512-aGRDY0r5jx9+OOgFdyB9Xm3EBr9OUmcrTDPWLB7a7g8VPRxzPy4MOBmcVYgz7ErhAJ7bZ/coUoj6aHio3x/2mA== @@ -3806,14 +3967,14 @@ packages: vfile-message: 2.0.4 dev: true - /memoize-one/6.0.0: + /memoize-one@6.0.0: resolution: { integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== } dev: true - /merge2/1.4.1: + /merge2@1.4.1: resolution: { integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -3821,7 +3982,7 @@ packages: engines: { node: '>= 8' } dev: true - /micromatch/4.0.5: + /micromatch@4.0.5: resolution: { integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -3832,7 +3993,7 @@ packages: picomatch: 2.3.1 dev: true - /mime-match/1.0.2: + /mime-match@1.0.2: resolution: { integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg== @@ -3841,7 +4002,7 @@ packages: wildcard: 1.1.2 dev: true - /mime/3.0.0: + /mime@3.0.0: resolution: { integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== @@ -3850,7 +4011,7 @@ packages: hasBin: true dev: true - /min-indent/1.0.1: + /min-indent@1.0.1: resolution: { integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== @@ -3858,7 +4019,7 @@ packages: engines: { node: '>=4' } dev: true - /minimatch/3.1.2: + /minimatch@3.1.2: resolution: { integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -3867,7 +4028,7 @@ packages: brace-expansion: 1.1.11 dev: true - /minimatch/5.1.6: + /minimatch@5.1.6: resolution: { integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== @@ -3877,21 +4038,21 @@ packages: brace-expansion: 2.0.1 dev: true - /minimist/1.2.8: + /minimist@1.2.8: resolution: { integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== } dev: true - /minisearch/6.0.1: + /minisearch@6.0.1: resolution: { integrity: sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg== } dev: true - /mkdirp/0.5.6: + /mkdirp@0.5.6: resolution: { integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -3901,7 +4062,7 @@ packages: minimist: 1.2.8 dev: true - /mri/1.2.0: + /mri@1.2.0: resolution: { integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== @@ -3909,7 +4070,7 @@ packages: engines: { node: '>=4' } dev: true - /mrmime/1.0.1: + /mrmime@1.0.1: resolution: { integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== @@ -3917,21 +4078,21 @@ packages: engines: { node: '>=10' } dev: true - /ms/2.1.2: + /ms@2.1.2: resolution: { integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== } dev: true - /murmurhash-js/1.0.0: + /murmurhash-js@1.0.0: resolution: { integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw== } dev: true - /mz/2.7.0: + /mz@2.7.0: resolution: { integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== @@ -3942,14 +4103,14 @@ packages: thenify-all: 1.6.0 dev: true - /namespace-emitter/2.0.1: + /namespace-emitter@2.0.1: resolution: { integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g== } dev: true - /nanoid/3.3.6: + /nanoid@3.3.6: resolution: { integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== @@ -3958,7 +4119,7 @@ packages: hasBin: true dev: true - /nanoid/4.0.2: + /nanoid@4.0.2: resolution: { integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== @@ -3967,28 +4128,43 @@ packages: hasBin: true dev: true - /natural-compare-lite/1.4.0: + /natural-compare-lite@1.4.0: resolution: { integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== } dev: true - /natural-compare/1.4.0: + /natural-compare@1.4.0: resolution: { integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== } dev: true - /node-releases/2.0.10: + /node-fetch@2.6.11: + resolution: + { + integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== + } + engines: { node: 4.x || >=6.0.0 } + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-releases@2.0.10: resolution: { integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== } dev: true - /normalize-path/3.0.0: + /normalize-path@3.0.0: resolution: { integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -3996,7 +4172,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /normalize-range/0.1.2: + /normalize-range@0.1.2: resolution: { integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== @@ -4004,7 +4180,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /nth-check/2.1.1: + /nth-check@2.1.1: resolution: { integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== @@ -4013,7 +4189,7 @@ packages: boolbase: 1.0.0 dev: true - /object-assign/4.1.1: + /object-assign@4.1.1: resolution: { integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -4021,7 +4197,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /object-hash/3.0.0: + /object-hash@3.0.0: resolution: { integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== @@ -4029,7 +4205,7 @@ packages: engines: { node: '>= 6' } dev: true - /once/1.4.0: + /once@1.4.0: resolution: { integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -4038,7 +4214,7 @@ packages: wrappy: 1.0.2 dev: true - /optionator/0.9.1: + /optionator@0.9.1: resolution: { integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== @@ -4053,7 +4229,7 @@ packages: word-wrap: 1.2.3 dev: true - /p-limit/2.3.0: + /p-limit@2.3.0: resolution: { integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -4063,7 +4239,7 @@ packages: p-try: 2.2.0 dev: true - /p-limit/3.1.0: + /p-limit@3.1.0: resolution: { integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -4073,7 +4249,7 @@ packages: yocto-queue: 0.1.0 dev: true - /p-locate/4.1.0: + /p-locate@4.1.0: resolution: { integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== @@ -4083,7 +4259,7 @@ packages: p-limit: 2.3.0 dev: true - /p-locate/5.0.0: + /p-locate@5.0.0: resolution: { integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== @@ -4093,7 +4269,7 @@ packages: p-limit: 3.1.0 dev: true - /p-queue/7.3.4: + /p-queue@7.3.4: resolution: { integrity: sha512-esox8CWt0j9EZECFvkFl2WNPat8LN4t7WWeXq73D9ha0V96qPRufApZi4ZhPwXAln1uVVal429HVVKPa2X0yQg== @@ -4104,7 +4280,7 @@ packages: p-timeout: 5.1.0 dev: true - /p-timeout/5.1.0: + /p-timeout@5.1.0: resolution: { integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew== @@ -4112,7 +4288,7 @@ packages: engines: { node: '>=12' } dev: true - /p-try/2.2.0: + /p-try@2.2.0: resolution: { integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== @@ -4120,7 +4296,7 @@ packages: engines: { node: '>=6' } dev: true - /parent-module/1.0.1: + /parent-module@1.0.1: resolution: { integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== @@ -4130,7 +4306,7 @@ packages: callsites: 3.1.0 dev: true - /path-exists/4.0.0: + /path-exists@4.0.0: resolution: { integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== @@ -4138,7 +4314,7 @@ packages: engines: { node: '>=8' } dev: true - /path-is-absolute/1.0.1: + /path-is-absolute@1.0.1: resolution: { integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== @@ -4146,7 +4322,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /path-key/3.1.1: + /path-key@3.1.1: resolution: { integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -4154,14 +4330,14 @@ packages: engines: { node: '>=8' } dev: true - /path-parse/1.0.7: + /path-parse@1.0.7: resolution: { integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== } dev: true - /path-type/4.0.0: + /path-type@4.0.0: resolution: { integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== @@ -4169,7 +4345,7 @@ packages: engines: { node: '>=8' } dev: true - /pbf/3.2.1: + /pbf@3.2.1: resolution: { integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ== @@ -4180,14 +4356,14 @@ packages: resolve-protobuf-schema: 2.1.0 dev: true - /picocolors/1.0.0: + /picocolors@1.0.0: resolution: { integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== } dev: true - /picomatch/2.3.1: + /picomatch@2.3.1: resolution: { integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -4195,7 +4371,7 @@ packages: engines: { node: '>=8.6' } dev: true - /pify/2.3.0: + /pify@2.3.0: resolution: { integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -4203,7 +4379,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /pikaso/2.7.6: + /pikaso@2.7.6: resolution: { integrity: sha512-QIGRGKFayu1zD3Bpkb8l76RPrGwEshpbUTnz8qKent92QQncWgAlG0YV6o3TpMaOBKTtn7aVm3JiNhrlzP66lA== @@ -4214,7 +4390,7 @@ packages: typescript: 4.9.5 dev: true - /pirates/4.0.5: + /pirates@4.0.5: resolution: { integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== @@ -4222,7 +4398,7 @@ packages: engines: { node: '>= 6' } dev: true - /plausible-tracker/0.3.8: + /plausible-tracker@0.3.8: resolution: { integrity: sha512-lmOWYQ7s9KOUJ1R+YTOR3HrjdbxIS2Z4de0P/Jx2dQPteznJl2eX3tXxKClpvbfyGP59B5bbhW8ftN59HbbFSg== @@ -4230,7 +4406,7 @@ packages: engines: { node: '>=10' } dev: true - /pngjs/5.0.0: + /pngjs@5.0.0: resolution: { integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== @@ -4238,7 +4414,7 @@ packages: engines: { node: '>=10.13.0' } dev: true - /postcss-calc/8.2.4_postcss@8.4.22: + /postcss-calc@8.2.4(postcss@8.4.22): resolution: { integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== @@ -4251,7 +4427,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-colormin/6.0.0_postcss@8.4.22: + /postcss-colormin@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw== @@ -4267,7 +4443,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-convert-values/6.0.0_postcss@8.4.22: + /postcss-convert-values@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw== @@ -4281,7 +4457,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-discard-comments/6.0.0_postcss@8.4.22: + /postcss-discard-comments@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw== @@ -4293,7 +4469,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-discard-duplicates/6.0.0_postcss@8.4.22: + /postcss-discard-duplicates@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA== @@ -4305,7 +4481,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-discard-empty/6.0.0_postcss@8.4.22: + /postcss-discard-empty@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ== @@ -4317,7 +4493,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-discard-overridden/6.0.0_postcss@8.4.22: + /postcss-discard-overridden@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw== @@ -4329,7 +4505,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-import/14.1.0_postcss@8.4.22: + /postcss-import@14.1.0(postcss@8.4.22): resolution: { integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== @@ -4344,7 +4520,7 @@ packages: resolve: 1.22.2 dev: true - /postcss-import/15.1.0_postcss@8.4.22: + /postcss-import@15.1.0(postcss@8.4.22): resolution: { integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== @@ -4359,7 +4535,7 @@ packages: resolve: 1.22.2 dev: true - /postcss-js/4.0.1_postcss@8.4.22: + /postcss-js@4.0.1(postcss@8.4.22): resolution: { integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== @@ -4372,7 +4548,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-load-config/3.1.4_postcss@8.4.22: + /postcss-load-config@3.1.4(postcss@8.4.22): resolution: { integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== @@ -4392,7 +4568,7 @@ packages: yaml: 1.10.2 dev: true - /postcss-load-config/4.0.1_postcss@8.4.22: + /postcss-load-config@4.0.1(postcss@8.4.22): resolution: { integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== @@ -4412,7 +4588,7 @@ packages: yaml: 2.2.1 dev: true - /postcss-merge-longhand/6.0.0_postcss@8.4.22: + /postcss-merge-longhand@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg== @@ -4423,10 +4599,10 @@ packages: dependencies: postcss: 8.4.22 postcss-value-parser: 4.2.0 - stylehacks: 6.0.0_postcss@8.4.22 + stylehacks: 6.0.0(postcss@8.4.22) dev: true - /postcss-merge-rules/6.0.0_postcss@8.4.22: + /postcss-merge-rules@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-rCXkklftzEkniyv3f4mRCQzxD6oE4Quyh61uyWTUbCJ26Pv2hoz+fivJSsSBWxDBeScR4fKCfF3HHTcD7Ybqnw== @@ -4437,12 +4613,12 @@ packages: dependencies: browserslist: 4.21.5 caniuse-api: 3.0.0 - cssnano-utils: 4.0.0_postcss@8.4.22 + cssnano-utils: 4.0.0(postcss@8.4.22) postcss: 8.4.22 postcss-selector-parser: 6.0.11 dev: true - /postcss-minify-font-values/6.0.0_postcss@8.4.22: + /postcss-minify-font-values@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA== @@ -4455,7 +4631,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-minify-gradients/6.0.0_postcss@8.4.22: + /postcss-minify-gradients@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA== @@ -4465,12 +4641,12 @@ packages: postcss: ^8.2.15 dependencies: colord: 2.9.3 - cssnano-utils: 4.0.0_postcss@8.4.22 + cssnano-utils: 4.0.0(postcss@8.4.22) postcss: 8.4.22 postcss-value-parser: 4.2.0 dev: true - /postcss-minify-params/6.0.0_postcss@8.4.22: + /postcss-minify-params@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ== @@ -4480,12 +4656,12 @@ packages: postcss: ^8.2.15 dependencies: browserslist: 4.21.5 - cssnano-utils: 4.0.0_postcss@8.4.22 + cssnano-utils: 4.0.0(postcss@8.4.22) postcss: 8.4.22 postcss-value-parser: 4.2.0 dev: true - /postcss-minify-selectors/6.0.0_postcss@8.4.22: + /postcss-minify-selectors@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g== @@ -4498,7 +4674,7 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-nested/6.0.0_postcss@8.4.22: + /postcss-nested@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== @@ -4511,7 +4687,7 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-normalize-charset/6.0.0_postcss@8.4.22: + /postcss-normalize-charset@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ== @@ -4523,7 +4699,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-normalize-display-values/6.0.0_postcss@8.4.22: + /postcss-normalize-display-values@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw== @@ -4536,7 +4712,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-positions/6.0.0_postcss@8.4.22: + /postcss-normalize-positions@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg== @@ -4549,7 +4725,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-repeat-style/6.0.0_postcss@8.4.22: + /postcss-normalize-repeat-style@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A== @@ -4562,7 +4738,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-string/6.0.0_postcss@8.4.22: + /postcss-normalize-string@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w== @@ -4575,7 +4751,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-timing-functions/6.0.0_postcss@8.4.22: + /postcss-normalize-timing-functions@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg== @@ -4588,7 +4764,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-unicode/6.0.0_postcss@8.4.22: + /postcss-normalize-unicode@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg== @@ -4602,7 +4778,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-url/6.0.0_postcss@8.4.22: + /postcss-normalize-url@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw== @@ -4615,7 +4791,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-whitespace/6.0.0_postcss@8.4.22: + /postcss-normalize-whitespace@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw== @@ -4628,7 +4804,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-ordered-values/6.0.0_postcss@8.4.22: + /postcss-ordered-values@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg== @@ -4637,12 +4813,12 @@ packages: peerDependencies: postcss: ^8.2.15 dependencies: - cssnano-utils: 4.0.0_postcss@8.4.22 + cssnano-utils: 4.0.0(postcss@8.4.22) postcss: 8.4.22 postcss-value-parser: 4.2.0 dev: true - /postcss-reduce-initial/6.0.0_postcss@8.4.22: + /postcss-reduce-initial@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA== @@ -4656,7 +4832,7 @@ packages: postcss: 8.4.22 dev: true - /postcss-reduce-transforms/6.0.0_postcss@8.4.22: + /postcss-reduce-transforms@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w== @@ -4669,7 +4845,7 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-selector-parser/6.0.10: + /postcss-selector-parser@6.0.10: resolution: { integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== @@ -4680,7 +4856,7 @@ packages: util-deprecate: 1.0.2 dev: true - /postcss-selector-parser/6.0.11: + /postcss-selector-parser@6.0.11: resolution: { integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== @@ -4691,7 +4867,7 @@ packages: util-deprecate: 1.0.2 dev: true - /postcss-svgo/6.0.0_postcss@8.4.22: + /postcss-svgo@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw== @@ -4705,7 +4881,7 @@ packages: svgo: 3.0.2 dev: true - /postcss-unique-selectors/6.0.0_postcss@8.4.22: + /postcss-unique-selectors@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw== @@ -4718,14 +4894,14 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /postcss-value-parser/4.2.0: + /postcss-value-parser@4.2.0: resolution: { integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== } dev: true - /postcss/8.4.22: + /postcss@8.4.22: resolution: { integrity: sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA== @@ -4737,21 +4913,21 @@ packages: source-map-js: 1.0.2 dev: true - /potpack/2.0.0: + /potpack@2.0.0: resolution: { integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw== } dev: true - /preact/10.13.2: + /preact@10.13.2: resolution: { integrity: sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw== } dev: true - /prelude-ls/1.2.1: + /prelude-ls@1.2.1: resolution: { integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== @@ -4759,7 +4935,7 @@ packages: engines: { node: '>= 0.8.0' } dev: true - /prettier-plugin-svelte/2.10.0_ur5pqdgn24bclu6l6i7qojopk4: + /prettier-plugin-svelte@2.10.0(prettier@2.8.7)(svelte@3.58.0): resolution: { integrity: sha512-GXMY6t86thctyCvQq+jqElO+MKdB09BkL3hexyGP3Oi8XLKRFaJP1ud/xlWCZ9ZIa2BxHka32zhHfcuU+XsRQg== @@ -4772,7 +4948,7 @@ packages: svelte: 3.58.0 dev: true - /prettier/2.8.7: + /prettier@2.8.7: resolution: { integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw== @@ -4781,14 +4957,14 @@ packages: hasBin: true dev: true - /prism-svelte/0.4.7: + /prism-svelte@0.4.7: resolution: { integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ== } dev: true - /prismjs/1.29.0: + /prismjs@1.29.0: resolution: { integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== @@ -4796,7 +4972,7 @@ packages: engines: { node: '>=6' } dev: true - /promise-queue/2.2.5: + /promise-queue@2.2.5: resolution: { integrity: sha512-p/iXrPSVfnqPft24ZdNNLECw/UrtLTpT3jpAAMzl/o5/rDsGCPo3/CQS2611flL6LkoEJ3oQZw7C8Q80ZISXRQ== @@ -4804,21 +4980,21 @@ packages: engines: { node: '>= 0.8.0' } dev: true - /property-expr/2.0.5: + /property-expr@2.0.5: resolution: { integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA== } dev: true - /protocol-buffers-schema/3.6.0: + /protocol-buffers-schema@3.6.0: resolution: { integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw== } dev: true - /punycode/2.3.0: + /punycode@2.3.0: resolution: { integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== @@ -4826,7 +5002,7 @@ packages: engines: { node: '>=6' } dev: true - /qrcode/1.5.1: + /qrcode@1.5.1: resolution: { integrity: sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg== @@ -4840,14 +5016,14 @@ packages: yargs: 15.4.1 dev: true - /queue-microtask/1.2.3: + /queue-microtask@1.2.3: resolution: { integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== } dev: true - /quick-lru/5.1.1: + /quick-lru@5.1.1: resolution: { integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== @@ -4855,14 +5031,14 @@ packages: engines: { node: '>=10' } dev: true - /quickselect/2.0.0: + /quickselect@2.0.0: resolution: { integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== } dev: true - /read-cache/1.0.0: + /read-cache@1.0.0: resolution: { integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== @@ -4871,7 +5047,7 @@ packages: pify: 2.3.0 dev: true - /readdirp/3.6.0: + /readdirp@3.6.0: resolution: { integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== @@ -4881,13 +5057,13 @@ packages: picomatch: 2.3.1 dev: true - /regenerator-runtime/0.13.11: + /regenerator-runtime@0.13.11: resolution: { integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== } - /require-directory/2.1.1: + /require-directory@2.1.1: resolution: { integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== @@ -4895,14 +5071,14 @@ packages: engines: { node: '>=0.10.0' } dev: true - /require-main-filename/2.0.0: + /require-main-filename@2.0.0: resolution: { integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== } dev: true - /resolve-from/4.0.0: + /resolve-from@4.0.0: resolution: { integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== @@ -4910,7 +5086,7 @@ packages: engines: { node: '>=4' } dev: true - /resolve-protobuf-schema/2.1.0: + /resolve-protobuf-schema@2.1.0: resolution: { integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ== @@ -4919,7 +5095,15 @@ packages: protocol-buffers-schema: 3.6.0 dev: true - /resolve/1.22.2: + /resolve-url@0.2.1: + resolution: + { + integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + } + deprecated: https://github.com/lydell/resolve-url#deprecated + dev: true + + /resolve@1.22.2: resolution: { integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== @@ -4931,7 +5115,7 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true - /reusify/1.0.4: + /reusify@1.0.4: resolution: { integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== @@ -4939,7 +5123,7 @@ packages: engines: { iojs: '>=1.0.0', node: '>=0.10.0' } dev: true - /rimraf/2.7.1: + /rimraf@2.7.1: resolution: { integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -4949,7 +5133,7 @@ packages: glob: 7.2.3 dev: true - /rimraf/3.0.2: + /rimraf@3.0.2: resolution: { integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -4959,7 +5143,7 @@ packages: glob: 7.2.3 dev: true - /rollup/3.20.6: + /rollup@3.20.6: resolution: { integrity: sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw== @@ -4970,7 +5154,7 @@ packages: fsevents: 2.3.2 dev: true - /run-parallel/1.2.0: + /run-parallel@1.2.0: resolution: { integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== @@ -4979,14 +5163,14 @@ packages: queue-microtask: 1.2.3 dev: true - /rw/1.3.3: + /rw@1.3.3: resolution: { integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== } dev: true - /sade/1.8.1: + /sade@1.8.1: resolution: { integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== @@ -4996,14 +5180,14 @@ packages: mri: 1.2.0 dev: true - /safe-buffer/5.2.1: + /safe-buffer@5.2.1: resolution: { integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== } dev: true - /sander/0.5.1: + /sander@0.5.1: resolution: { integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA== @@ -5015,7 +5199,7 @@ packages: rimraf: 2.7.1 dev: true - /sass/1.62.0: + /sass@1.62.0: resolution: { integrity: sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg== @@ -5028,7 +5212,7 @@ packages: source-map-js: 1.0.2 dev: true - /semver/7.5.0: + /semver@7.5.0: resolution: { integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== @@ -5039,21 +5223,21 @@ packages: lru-cache: 6.0.0 dev: true - /set-blocking/2.0.0: + /set-blocking@2.0.0: resolution: { integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== } dev: true - /set-cookie-parser/2.6.0: + /set-cookie-parser@2.6.0: resolution: { integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ== } dev: true - /shebang-command/2.0.0: + /shebang-command@2.0.0: resolution: { integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== @@ -5063,7 +5247,7 @@ packages: shebang-regex: 3.0.0 dev: true - /shebang-regex/3.0.0: + /shebang-regex@3.0.0: resolution: { integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== @@ -5071,7 +5255,7 @@ packages: engines: { node: '>=8' } dev: true - /sirv/2.0.2: + /sirv@2.0.2: resolution: { integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w== @@ -5083,7 +5267,7 @@ packages: totalist: 3.0.1 dev: true - /slash/3.0.0: + /slash@3.0.0: resolution: { integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== @@ -5091,7 +5275,7 @@ packages: engines: { node: '>=8' } dev: true - /socket.io-client/4.6.1: + /socket.io-client@4.6.1: resolution: { integrity: sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ== @@ -5108,7 +5292,7 @@ packages: - utf-8-validate dev: true - /socket.io-parser/4.2.2: + /socket.io-parser@4.2.2: resolution: { integrity: sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw== @@ -5121,7 +5305,7 @@ packages: - supports-color dev: true - /sorcery/0.11.0: + /sorcery@0.11.0: resolution: { integrity: sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw== @@ -5134,7 +5318,7 @@ packages: sander: 0.5.1 dev: true - /source-map-js/1.0.2: + /source-map-js@1.0.2: resolution: { integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -5142,14 +5326,14 @@ packages: engines: { node: '>=0.10.0' } dev: true - /ssr-window/4.0.2: + /ssr-window@4.0.2: resolution: { integrity: sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ== } dev: true - /streamsearch/1.1.0: + /streamsearch@1.1.0: resolution: { integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== @@ -5157,7 +5341,7 @@ packages: engines: { node: '>=10.0.0' } dev: true - /string-width/4.2.3: + /string-width@4.2.3: resolution: { integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5169,7 +5353,7 @@ packages: strip-ansi: 6.0.1 dev: true - /strip-ansi/6.0.1: + /strip-ansi@6.0.1: resolution: { integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5179,7 +5363,7 @@ packages: ansi-regex: 5.0.1 dev: true - /strip-indent/3.0.0: + /strip-indent@3.0.0: resolution: { integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== @@ -5189,7 +5373,7 @@ packages: min-indent: 1.0.1 dev: true - /strip-json-comments/3.1.1: + /strip-json-comments@3.1.1: resolution: { integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -5197,7 +5381,7 @@ packages: engines: { node: '>=8' } dev: true - /stylehacks/6.0.0_postcss@8.4.22: + /stylehacks@6.0.0(postcss@8.4.22): resolution: { integrity: sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw== @@ -5211,7 +5395,7 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /sucrase/3.32.0: + /sucrase@3.32.0: resolution: { integrity: sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== @@ -5228,7 +5412,7 @@ packages: ts-interface-checker: 0.1.13 dev: true - /supercluster/7.1.5: + /supercluster@7.1.5: resolution: { integrity: sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg== @@ -5237,7 +5421,7 @@ packages: kdbush: 3.0.0 dev: true - /supports-color/7.2.0: + /supports-color@7.2.0: resolution: { integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -5247,7 +5431,7 @@ packages: has-flag: 4.0.0 dev: true - /supports-preserve-symlinks-flag/1.0.0: + /supports-preserve-symlinks-flag@1.0.0: resolution: { integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== @@ -5255,7 +5439,7 @@ packages: engines: { node: '>= 0.4' } dev: true - /svelte-check/3.2.0_hgmayuytslzk7fmzhfn6bohtwu: + /svelte-check@3.2.0(postcss-load-config@4.0.1)(postcss@8.4.22)(sass@1.62.0)(svelte@3.58.0): resolution: { integrity: sha512-6ZnscN8dHEN5Eq5LgIzjj07W9nc9myyBH+diXsUAuiY/3rt0l65/LCIQYlIuoFEjp2F1NhXqZiJwV9omPj9tMw== @@ -5271,7 +5455,7 @@ packages: picocolors: 1.0.0 sade: 1.8.1 svelte: 3.58.0 - svelte-preprocess: 5.0.3_nrvzyekqy4pqqdxa53xkquyj6e + svelte-preprocess: 5.0.3(postcss-load-config@4.0.1)(postcss@8.4.22)(sass@1.62.0)(svelte@3.58.0)(typescript@5.0.4) typescript: 5.0.4 transitivePeerDependencies: - '@babel/core' @@ -5285,7 +5469,7 @@ packages: - sugarss dev: true - /svelte-hmr/0.15.1_svelte@3.58.0: + /svelte-hmr@0.15.1(svelte@3.58.0): resolution: { integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA== @@ -5297,7 +5481,7 @@ packages: svelte: 3.58.0 dev: true - /svelte-preprocess/5.0.3_nrvzyekqy4pqqdxa53xkquyj6e: + /svelte-preprocess@5.0.3(postcss-load-config@4.0.1)(postcss@8.4.22)(sass@1.62.0)(svelte@3.58.0)(typescript@5.0.4): resolution: { integrity: sha512-GrHF1rusdJVbOZOwgPWtpqmaexkydznKzy5qIC2FabgpFyKN57bjMUUUqPRfbBXK5igiEWn1uO/DXsa2vJ5VHA== @@ -5342,7 +5526,7 @@ packages: detect-indent: 6.1.0 magic-string: 0.27.0 postcss: 8.4.22 - postcss-load-config: 4.0.1_postcss@8.4.22 + postcss-load-config: 4.0.1(postcss@8.4.22) sass: 1.62.0 sorcery: 0.11.0 strip-indent: 3.0.0 @@ -5350,14 +5534,14 @@ packages: typescript: 5.0.4 dev: true - /svelte-range-slider-pips/2.1.1: + /svelte-range-slider-pips@2.1.1: resolution: { integrity: sha512-fLkhfnyEc4uMOCZCl8IPyC0e9lujrjqdSyrKw28Y8j99YUPZR+pHnSxde7PqhM0ST6eyO4ugh2nFnLZTIoG9aQ== } dev: true - /svelte-tippy/1.3.2: + /svelte-tippy@1.3.2: resolution: { integrity: sha512-41f+85hwhKBRqX0UNYrgFsi34Kk/KDvUkIZXYANxkWoA2NTVTCZbUC2J8hRNZ4TRVxObTshoZRjK2co5+i6LMw== @@ -5366,7 +5550,7 @@ packages: tippy.js: 6.3.7 dev: true - /svelte/3.58.0: + /svelte@3.58.0: resolution: { integrity: sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A== @@ -5374,7 +5558,7 @@ packages: engines: { node: '>= 8' } dev: true - /svgo/3.0.2: + /svgo@3.0.2: resolution: { integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ== @@ -5390,7 +5574,7 @@ packages: picocolors: 1.0.0 dev: true - /swiper/8.4.7: + /swiper@8.4.7: resolution: { integrity: sha512-VwO/KU3i9IV2Sf+W2NqyzwWob4yX9Qdedq6vBtS0rFqJ6Fa5iLUJwxQkuD4I38w0WDJwmFl8ojkdcRFPHWD+2g== @@ -5402,7 +5586,7 @@ packages: ssr-window: 4.0.2 dev: true - /tailwindcss/3.3.1_postcss@8.4.22: + /tailwindcss@3.3.1(postcss@8.4.22): resolution: { integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g== @@ -5427,10 +5611,10 @@ packages: object-hash: 3.0.0 picocolors: 1.0.0 postcss: 8.4.22 - postcss-import: 14.1.0_postcss@8.4.22 - postcss-js: 4.0.1_postcss@8.4.22 - postcss-load-config: 3.1.4_postcss@8.4.22 - postcss-nested: 6.0.0_postcss@8.4.22 + postcss-import: 14.1.0(postcss@8.4.22) + postcss-js: 4.0.1(postcss@8.4.22) + postcss-load-config: 3.1.4(postcss@8.4.22) + postcss-nested: 6.0.0(postcss@8.4.22) postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 quick-lru: 5.1.1 @@ -5440,14 +5624,14 @@ packages: - ts-node dev: true - /text-table/0.2.0: + /text-table@0.2.0: resolution: { integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== } dev: true - /thenify-all/1.6.0: + /thenify-all@1.6.0: resolution: { integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== @@ -5457,7 +5641,7 @@ packages: thenify: 3.3.1 dev: true - /thenify/3.3.1: + /thenify@3.3.1: resolution: { integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== @@ -5466,14 +5650,21 @@ packages: any-promise: 1.3.0 dev: true - /tiny-case/1.0.3: + /thumbhash@0.1.1: + resolution: + { + integrity: sha512-kH5pKeIIBPQXAOni2AiY/Cu/NKdkFREdpH+TLdM0g6WA7RriCv0kPLgP731ady67MhTAqrVG/4mnEeibVuCJcg== + } + dev: true + + /tiny-case@1.0.3: resolution: { integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== } dev: true - /tiny-glob/0.2.9: + /tiny-glob@0.2.9: resolution: { integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== @@ -5483,14 +5674,14 @@ packages: globrex: 0.1.2 dev: true - /tinyqueue/2.0.3: + /tinyqueue@2.0.3: resolution: { integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA== } dev: true - /tippy.js/6.3.7: + /tippy.js@6.3.7: resolution: { integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ== @@ -5499,7 +5690,7 @@ packages: '@popperjs/core': 2.11.7 dev: true - /to-regex-range/5.0.1: + /to-regex-range@5.0.1: resolution: { integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== @@ -5509,14 +5700,14 @@ packages: is-number: 7.0.0 dev: true - /toposort/2.0.2: + /toposort@2.0.2: resolution: { integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== } dev: true - /totalist/3.0.1: + /totalist@3.0.1: resolution: { integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== @@ -5524,28 +5715,35 @@ packages: engines: { node: '>=6' } dev: true - /ts-interface-checker/0.1.13: + /tr46@0.0.3: + resolution: + { + integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + } + dev: true + + /ts-interface-checker@0.1.13: resolution: { integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== } dev: true - /tslib/1.14.1: + /tslib@1.14.1: resolution: { integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== } dev: true - /tslib/2.5.0: + /tslib@2.5.0: resolution: { integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== } dev: true - /tsutils/3.21.0_typescript@5.0.4: + /tsutils@3.21.0(typescript@5.0.4): resolution: { integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== @@ -5558,7 +5756,7 @@ packages: typescript: 5.0.4 dev: true - /type-check/0.4.0: + /type-check@0.4.0: resolution: { integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== @@ -5568,7 +5766,7 @@ packages: prelude-ls: 1.2.1 dev: true - /type-fest/0.20.2: + /type-fest@0.20.2: resolution: { integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== @@ -5576,7 +5774,7 @@ packages: engines: { node: '>=10' } dev: true - /type-fest/2.19.0: + /type-fest@2.19.0: resolution: { integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== @@ -5584,7 +5782,7 @@ packages: engines: { node: '>=12.20' } dev: true - /typescript/4.9.5: + /typescript@4.9.5: resolution: { integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -5593,7 +5791,7 @@ packages: hasBin: true dev: true - /typescript/5.0.4: + /typescript@5.0.4: resolution: { integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== @@ -5602,14 +5800,14 @@ packages: hasBin: true dev: true - /ua-parser-js/1.0.35: + /ua-parser-js@1.0.35: resolution: { integrity: sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA== } dev: true - /undici/5.20.0: + /undici@5.20.0: resolution: { integrity: sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g== @@ -5619,7 +5817,7 @@ packages: busboy: 1.6.0 dev: true - /unist-util-stringify-position/2.0.3: + /unist-util-stringify-position@2.0.3: resolution: { integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== @@ -5628,7 +5826,21 @@ packages: '@types/unist': 2.0.6 dev: true - /update-browserslist-db/1.0.11_browserslist@4.21.5: + /unlazy@0.8.9(fast-blurhash@1.1.2)(thumbhash@0.1.1): + resolution: + { + integrity: sha512-lRCuXN20N1esqSQqtSVBLAw9GJz0lcBuOBs3UGGw7cFWHQlWJVZZ3OviwOl42f1CnVHjAON1rs2hIdJWgMAUyg== + } + peerDependencies: + fast-blurhash: ^1.1.2 + thumbhash: ^0.1.1 + dependencies: + '@unlazy/core': 0.8.9 + fast-blurhash: 1.1.2 + thumbhash: 0.1.1 + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: { integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== @@ -5642,7 +5854,7 @@ packages: picocolors: 1.0.0 dev: true - /uri-js/4.4.1: + /uri-js@4.4.1: resolution: { integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== @@ -5651,14 +5863,14 @@ packages: punycode: 2.3.0 dev: true - /util-deprecate/1.0.2: + /util-deprecate@1.0.2: resolution: { integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== } dev: true - /vfile-message/2.0.4: + /vfile-message@2.0.4: resolution: { integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== @@ -5668,7 +5880,14 @@ packages: unist-util-stringify-position: 2.0.3 dev: true - /vite-plugin-iso-import/1.0.0_vite@4.2.2: + /vite-plugin-cross-origin-isolation@0.1.6: + resolution: + { + integrity: sha512-OY0naW9nPUDrKTffYnY7FRYXOgZdHoNwMGpPxUmj/n32mGZi01fcq+J536jkmwGWX7DLT95XBQVHHbrAJzTvrw== + } + dev: true + + /vite-plugin-iso-import@1.0.0(vite@4.2.2): resolution: { integrity: sha512-DqhCElHfkbkqLXtm0UMiAXqh9FdqRHegHpawXtp5LWHjGsdAqYPhmUGBTKFuTRwPSNFYCpyjHRsm7lvM2dskGw== @@ -5678,10 +5897,10 @@ packages: dependencies: es-module-lexer: 1.2.1 magic-string: 0.27.0 - vite: 4.2.2_sass@1.62.0 + vite: 4.2.2(sass@1.62.0) dev: true - /vite/4.2.2_sass@1.62.0: + /vite@4.2.2(sass@1.62.0): resolution: { integrity: sha512-PcNtT5HeDxb3QaSqFYkEum8f5sCVe0R3WK20qxgIvNBZPXU/Obxs/+ubBMeE7nLWeCo2LDzv+8hRYSlcaSehig== @@ -5718,7 +5937,7 @@ packages: fsevents: 2.3.2 dev: true - /vitefu/0.2.4_vite@4.2.2: + /vitefu@0.2.4(vite@4.2.2): resolution: { integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g== @@ -5729,10 +5948,10 @@ packages: vite: optional: true dependencies: - vite: 4.2.2_sass@1.62.0 + vite: 4.2.2(sass@1.62.0) dev: true - /vt-pbf/3.1.3: + /vt-pbf@3.1.3: resolution: { integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== @@ -5743,14 +5962,31 @@ packages: pbf: 3.2.1 dev: true - /which-module/2.0.0: + /webidl-conversions@3.0.1: + resolution: + { + integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + } + dev: true + + /whatwg-url@5.0.0: + resolution: + { + integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + } + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /which-module@2.0.0: resolution: { integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== } dev: true - /which/2.0.2: + /which@2.0.2: resolution: { integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -5761,14 +5997,14 @@ packages: isexe: 2.0.0 dev: true - /wildcard/1.1.2: + /wildcard@1.1.2: resolution: { integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng== } dev: true - /word-wrap/1.2.3: + /word-wrap@1.2.3: resolution: { integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -5776,7 +6012,7 @@ packages: engines: { node: '>=0.10.0' } dev: true - /wrap-ansi/6.2.0: + /wrap-ansi@6.2.0: resolution: { integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== @@ -5788,14 +6024,14 @@ packages: strip-ansi: 6.0.1 dev: true - /wrappy/1.0.2: + /wrappy@1.0.2: resolution: { integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== } dev: true - /ws/8.11.0: + /ws@8.11.0: resolution: { integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== @@ -5811,7 +6047,7 @@ packages: optional: true dev: true - /xmlhttprequest-ssl/2.0.0: + /xmlhttprequest-ssl@2.0.0: resolution: { integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== @@ -5819,21 +6055,21 @@ packages: engines: { node: '>=0.4.0' } dev: true - /y18n/4.0.3: + /y18n@4.0.3: resolution: { integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== } dev: true - /yallist/4.0.0: + /yallist@4.0.0: resolution: { integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== } dev: true - /yaml/1.10.2: + /yaml@1.10.2: resolution: { integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== @@ -5841,7 +6077,7 @@ packages: engines: { node: '>= 6' } dev: true - /yaml/2.2.1: + /yaml@2.2.1: resolution: { integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw== @@ -5849,7 +6085,7 @@ packages: engines: { node: '>= 14' } dev: true - /yargs-parser/18.1.3: + /yargs-parser@18.1.3: resolution: { integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== @@ -5860,7 +6096,7 @@ packages: decamelize: 1.2.0 dev: true - /yargs/15.4.1: + /yargs@15.4.1: resolution: { integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== @@ -5880,7 +6116,7 @@ packages: yargs-parser: 18.1.3 dev: true - /yocto-queue/0.1.0: + /yocto-queue@0.1.0: resolution: { integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== @@ -5888,7 +6124,7 @@ packages: engines: { node: '>=10' } dev: true - /yup/1.1.1: + /yup@1.1.1: resolution: { integrity: sha512-KfCGHdAErqFZWA5tZf7upSUnGKuTOnsI3hUsLr7fgVtx+DK04NPV01A68/FslI4t3s/ZWpvXJmgXhd7q6ICnag== diff --git a/frontend/src/lib/admin.svelte b/frontend/src/lib/admin.svelte index b856d4f..826e737 100644 --- a/frontend/src/lib/admin.svelte +++ b/frontend/src/lib/admin.svelte @@ -14,6 +14,7 @@ import CircularTimer from '$lib/play/circular_progress.svelte'; import Spinner from '$lib/Spinner.svelte'; import { get_foreground_color } from '$lib/helpers'; + import MediaComponent from '$lib/editor/MediaComponent.svelte'; export let game_token: string; export let quiz_data: QuizData; @@ -223,11 +224,11 @@ {#if quiz_data.questions[selected_question].image !== null} -
Placeholder
+{:then data} + {#if type === 'img'} +Unknown media type
+ {/if} +{/await} diff --git a/frontend/src/lib/editor/card.svelte b/frontend/src/lib/editor/card.svelte index 5540a81..d4c6b4d 100644 --- a/frontend/src/lib/editor/card.svelte +++ b/frontend/src/lib/editor/card.svelte @@ -10,22 +10,21 @@ import { reach } from 'yup'; import { dataSchema } from '$lib/yupSchemas'; import Spinner from '../Spinner.svelte'; - import { createTippy } from 'svelte-tippy'; + // import { createTippy } from 'svelte-tippy'; import { getLocalization } from '$lib/i18n'; + // import MediaComponent from "$lib/editor/MediaComponent.svelte"; const { t } = getLocalization(); - const tippy = createTippy({ - arrow: true, - animation: 'perspective-subtle', - placement: 'top' - }); + /* const tippy = createTippy({ + arrow: true, + animation: 'perspective-subtle', + placement: 'top' + });*/ export let data: EditorData; export let selected_question: number; export let edit_id: string; - export let pow_data; - export let pow_salt: string; let uppyOpen = false; let unique = {}; @@ -51,6 +50,17 @@ selected_question; set_unique(); } + let image_url = ''; + + const update_image_url = () => { + image_url = data.questions[selected_question].image; + console.log('updated!'); + }; + $: { + update_image_url(); + selected_question; + data.questions; + } /* if (typeof data.questions[selected_question].type !== QuizQuestionType) { console.log(data.questions[selected_question].type !== QuizQuestionType.ABCD || data.questions[selected_question].type !== QuizQuestionType.RANGE) @@ -60,7 +70,7 @@+ {$t('uploader.upload_video_popup_notice')} +
+ {:else} +{image.filename ?? 'No name available'}
+caddy run
+ arq classquiz.worker.WorkerSettings
+ If you're done developing: ./run_tests.sh -
If you want to run all the tests: ./run_tests.sh a
You'll have to set up a storage provider for some pictures (these getting imported from
- KAHOOT!). For now, you can use Deta or the local filesystem.
- Please note that I would NOT use the local file system because of
- Path Traversals. I tried to
- prevent these attacks, but I really wouldn't trust it, because it's a regex! You'll have to
- set the
- STORAGE_BACKEND-environment-variable to either deta or
- local.
+ Kahoot!). For now, you can use Minio (S3) or
+ the local filesystem. Please not that I'd recommend Minio for larger instances, since it can
+ be scaled and the media doesn't have to streamed through the (comparatively) slow ClassQuiz
+ server. Now, that you've decided on a storage backend, you can set the
+ STORAGE_BACKEND-environment-variable to either s3 or
+ local. If you ask yourself what happened with deta, I've decided to remove it,
+ since the went all-in with their spaces and I think that hardly anyone used it anyway.
- ...you'll also have to set the DETA_PROJECT_KEY and the
- DETA_PROJECT_ID.
+ ...you'll also have to set the S3_ACCESS_KEY, S3_SECRET_KEY and
+ the
+ S3_BASE_URL. The S3_BUCKET_NAME can also be set, but defaults to
+ classquiz.
@@ -165,15 +167,15 @@ services: REDIS_URL: redis://redis:6379/0?decode_responses=True # don't change API_URL: http://api:80 # don't change api: - build: + build: &build_cfg context: . dockerfile: Dockerfile - restart: always - depends_on: + restart: &restart always + depends_on: &depends - db - redis - environment: + environment: &env_vars ROOT_ADDRESS: "https://classquiz.de" # Base-URL (change it) DB_URL: "postgresql://postgres:classquiz@db:5432/classquiz" # don't change MAIL_ADDRESS: "classquiz@mawoka.eu" # Email-Address (change it) @@ -188,11 +190,13 @@ services: MEILISEARCH_URL: "http://meilisearch:7700" # don't change ACCESS_TOKEN_EXPIRE_MINUTES: 30 # don't change HCAPTCHA_KEY: "" # Private hCaptcha key for verification (change it) - STORAGE_BACKEND: "deta" # MUST BE EITHER "deta" OR "local" + STORAGE_BACKEND: "local" # MUST BE EITHER "s3" OR "local" + FREE_STORAGE_LIMIT: "1074000000" # Free storage limit in bytes (default: 1GB) - # If STORAGE_BACKEND is "deta" - DETA_PROJECT_KEY: "YOUR_DETA_PROJECT_KEY" - DETA_PROJECT_ID: "YOUR_DETA_PROJECT_ID" + # If STORAGE_BACKEND is "s3" + S3_ACCESS_KEY=YOUR_ACCESS_KEY + S3_SECRET_KEY=YOUR_SECRET_KEY + S3_BASE_URL=YOUR_S3_BASE_URL # If STORAGE_BACKEND is "local" STORAGE_PATH: "/var/storage" @@ -205,6 +209,8 @@ services: GITHUB_CLIENT_ID: # Your GitHub-Client ID, or leave it unset if you don't want it. GITHUB_CLIENT_SECRET: # Your GitHub-Client Secret, or leave it unset if you don't want it. + volumes: # Only needed if you chose the "local" storage-backend + - ./uploads:/var/storage redis: image: redis:alpine @@ -241,6 +247,14 @@ services: MEILI_NO_ANALYTICS: true volumes: - meilisearch-data:/data.ms + worker: + build: *build_cfg + environment: *env_vars + restart: *restart + depends_on: *depends + command: arq classquiz.worker.WorkerSettings + + volumes: data: meilisearch-data: diff --git a/frontend/src/routes/edit/files/+page.svelte b/frontend/src/routes/edit/files/+page.svelte new file mode 100644 index 0000000..8aa7ea2 --- /dev/null +++ b/frontend/src/routes/edit/files/+page.svelte @@ -0,0 +1,157 @@ + + + + +
+ {$t('file_dashboard.size', { + size: (image.size / (1024 * 1024)).toFixed(2) + })} +
++ {$t('file_dashboard.caption', { + caption: image.alt_text ?? $t('file_dashboard.missing') + })} +
++ {$t('file_dashboard.filename', { + filename: image.filename ?? $t('file_dashboard.missing') + })} +
++ {$t('file_dashboard.uploaded', { + date: new Date(image.uploaded_at).toLocaleString() + })} +
++ {$t('file_dashboard.imported', { + yes_or_no: image.imported ? $t('words.yes') : $t('words.no') + })} +
+| {$t('words.speed')} | +{$t('words.progress')} | +{$t('video_uploader.time_elapsed')} | +{$t('video_uploader.time_remaining')} | +
|---|---|---|---|
| {stats.speed} | +{Math.round(stats.progress * 100)}% | +{upload_stats.time_elapsed.toFixed(2)}s | +{(stats.time_elapsed / stats.progress - upload_stats.time_elapsed).toFixed( + 2 + )}s | +
| {$t('words.progress')} | +{$t('video_uploader.time_elapsed')} | +{$t('video_uploader.time_remaining')} | +
|---|---|---|
| {Math.round(upload_stats.progress * 100)}% | +{stats.time_elapsed.toFixed(2)}s | +{(stats.time_elapsed / stats.progress - stats.time_elapsed).toFixed(2)}s | +