diff --git a/Pipfile b/Pipfile index 164ec7d86..06c48bdab 100644 --- a/Pipfile +++ b/Pipfile @@ -142,7 +142,6 @@ django-storages = {extras = ["google"] } aiohttp = {extras = ["speedups"] } aiodns = "*" eventlet = "*" -linked-services = {extras = ["django", "aiohttp", "requests"] } celery-task-manager = {extras = ["django"] } django-sql-explorer = {extras = ["xls"] } contextlib2 = "*" @@ -157,3 +156,4 @@ pyright = "*" mypy = "*" python-magic = "*" uvicorn = {extras = ["standard"], version = "*"} +linked-services = {extras = ["requests", "django", "aiohttp"], version = "*"} diff --git a/Pipfile.lock b/Pipfile.lock index 8cc74ee1d..6584e0568 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d2ee64c6b137e5b6f7779f8636359bf20c5fa998957dcec482371fae7ed610c2" + "sha256": "a00a69326bd0652028d170b338670fa0d58264ad2493e832468b593b9d8285bc" }, "pipfile-spec": 6, "requires": {}, @@ -25,12 +25,12 @@ }, "adrf": { "hashes": [ - "sha256:18844630dd9272c38cc3f761fce6bfb50f91c4f84dadf99846f86d4527f19c7f", - "sha256:3032b987085d75cfd59eb3d4dcd7138fc20085de1782b065603559ccec69531f" + "sha256:e2f59fd84960a564b0385d9201c55531a30c6118eb40c86c5356c077f279af23", + "sha256:fd6c45df908e042c91571fdcff1ea54180c871ec18659b639cf3217d67ce97d5" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.1.8" + "version": "==0.1.9" }, "aiodns": { "hashes": [ @@ -42,135 +42,120 @@ }, "aiohappyeyeballs": { "hashes": [ - "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586", - "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572" + "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", + "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8" ], "markers": "python_version >= '3.8'", - "version": "==2.4.3" + "version": "==2.4.4" }, "aiohttp": { "extras": [ "speedups" ], "hashes": [ - "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138", - "sha256:00819de9e45d42584bed046314c40ea7e9aea95411b38971082cad449392b08c", - "sha256:01948b1d570f83ee7bbf5a60ea2375a89dfb09fd419170e7f5af029510033d24", - "sha256:038f514fe39e235e9fef6717fbf944057bfa24f9b3db9ee551a7ecf584b5b480", - "sha256:03a42ac7895406220124c88911ebee31ba8b2d24c98507f4a8bf826b2937c7f2", - "sha256:05646ebe6b94cc93407b3bf34b9eb26c20722384d068eb7339de802154d61bc5", - "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a", - "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8", - "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf", - "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871", - "sha256:1b66ccafef7336a1e1f0e389901f60c1d920102315a56df85e49552308fc0486", - "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9", - "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d", - "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb", - "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68", - "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1", - "sha256:28529e08fde6f12eba8677f5a8608500ed33c086f974de68cc65ab218713a59d", - "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd", - "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1", - "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8", - "sha256:3455522392fb15ff549d92fbf4b73b559d5e43dc522588f7eb3e54c3f38beee7", - "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959", - "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7", - "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42", - "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79", - "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38", - "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a", - "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8", - "sha256:45c3b868724137f713a38376fef8120c166d1eadd50da1855c112fe97954aed8", - "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151", - "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6", - "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e", - "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7", - "sha256:54ca74df1be3c7ca1cf7f4c971c79c2daf48d9aa65dea1a662ae18926f5bc8ce", - "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b", - "sha256:597a079284b7ee65ee102bc3a6ea226a37d2b96d0418cc9047490f231dc09fe8", - "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628", - "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f", - "sha256:64f6c17757251e2b8d885d728b6433d9d970573586a78b78ba8929b0f41d045a", - "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7", - "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc", - "sha256:7789050d9e5d0c309c706953e5e8876e38662d57d45f936902e176d19f1c58ab", - "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b", - "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911", - "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9", - "sha256:7e338c0523d024fad378b376a79faff37fafb3c001872a618cde1d322400a572", - "sha256:7ea7ffc6d6d6f8a11e6f40091a1040995cdff02cfc9ba4c2f30a516cb2633554", - "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d", - "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257", - "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c", - "sha256:93429602396f3383a797a2a70e5f1de5df8e35535d7806c9f91df06f297e109b", - "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742", - "sha256:998f3bd3cfc95e9424a6acd7840cbdd39e45bc09ef87533c006f94ac47296090", - "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6", - "sha256:9fc1500fd2a952c5c8e3b29aaf7e3cc6e27e9cfc0a8819b3bce48cc1b849e4cc", - "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142", - "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16", - "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a", - "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28", - "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e", - "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94", - "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026", - "sha256:acd48d5b80ee80f9432a165c0ac8cbf9253eaddb6113269a5e18699b33958dbb", - "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28", - "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9", - "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3", - "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f", - "sha256:c02a30b904282777d872266b87b20ed8cc0d1501855e27f831320f471d54d983", - "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205", - "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f", - "sha256:c5ce2ce7c997e1971b7184ee37deb6ea9922ef5163c6ee5aa3c274b05f9e12fa", - "sha256:c823bc3971c44ab93e611ab1a46b1eafeae474c0c844aff4b7474287b75fe49c", - "sha256:ce0cdc074d540265bfeb31336e678b4e37316849d13b308607efa527e981f5c2", - "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb", - "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67", - "sha256:d9010c31cd6fa59438da4e58a7f19e4753f7f264300cd152e7f90d4602449762", - "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a", - "sha256:da1dee8948d2137bb51fbb8a53cce6b1bcc86003c6b42565f008438b806cccd8", - "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a", - "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a", - "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc", - "sha256:e7f8b04d83483577fd9200461b057c9f14ced334dcb053090cea1da9c8321a91", - "sha256:edfe3341033a6b53a5c522c802deb2079eee5cbfbb0af032a55064bd65c73a23", - "sha256:ef9c33cc5cbca35808f6c74be11eb7f5f6b14d2311be84a15b594bd3e58b5527", - "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6", - "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c", - "sha256:f614ab0c76397661b90b6851a030004dac502e48260ea10f2441abd2207fbcc7", - "sha256:f7db54c7914cc99d901d93a34704833568d86c20925b2762f9fa779f9cd2e70f", - "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a", - "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092", - "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414" + "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f", + "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33", + "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1", + "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665", + "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9", + "sha256:10b4ff0ad793d98605958089fabfa350e8e62bd5d40aa65cdc69d6785859f94e", + "sha256:1642eceeaa5ab6c9b6dfeaaa626ae314d808188ab23ae196a34c9d97efb68350", + "sha256:1dac54e8ce2ed83b1f6b1a54005c87dfed139cf3f777fdc8afc76e7841101226", + "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d", + "sha256:1f21bb8d0235fc10c09ce1d11ffbd40fc50d3f08a89e4cf3a0c503dc2562247a", + "sha256:2170816e34e10f2fd120f603e951630f8a112e1be3b60963a1f159f5699059a6", + "sha256:21fef42317cf02e05d3b09c028712e1d73a9606f02467fd803f7c1f39cc59add", + "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e", + "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8", + "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03", + "sha256:3e23419d832d969f659c208557de4a123e30a10d26e1e14b73431d3c13444c2e", + "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2", + "sha256:44167fc6a763d534a6908bdb2592269b4bf30a03239bcb1654781adf5e49caf1", + "sha256:479b8c6ebd12aedfe64563b85920525d05d394b85f166b7873c8bde6da612f9c", + "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538", + "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5", + "sha256:4eed954b161e6b9b65f6be446ed448ed3921763cc432053ceb606f89d793927e", + "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9", + "sha256:568c1236b2fde93b7720f95a890741854c1200fba4a3471ff48b2934d2d93fd3", + "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438", + "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12", + "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3", + "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853", + "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287", + "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2", + "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9", + "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c", + "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55", + "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c", + "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e", + "sha256:8be8508d110d93061197fd2d6a74f7401f73b6d12f8822bbcd6d74f2b55d71b1", + "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c", + "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194", + "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773", + "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e", + "sha256:943a8b052e54dfd6439fd7989f67fc6a7f2138d0a2cf0a7de5f18aa4fe7eb3b1", + "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d", + "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600", + "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34", + "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3", + "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8", + "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8", + "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2", + "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff", + "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62", + "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac", + "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef", + "sha256:b540bd67cfb54e6f0865ceccd9979687210d7ed1a1cc8c01f8e67e2f1e883d28", + "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab", + "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104", + "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76", + "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e", + "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d", + "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a", + "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5", + "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745", + "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4", + "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99", + "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43", + "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da", + "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231", + "sha256:d6c9af134da4bc9b3bd3e6a70072509f295d10ee60c697826225b60b9959acdd", + "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d", + "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87", + "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886", + "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2", + "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b", + "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d", + "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f", + "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204", + "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e" ], - "markers": "python_version >= '3.8'", - "version": "==3.10.10" + "markers": "python_version >= '3.9'", + "version": "==3.11.11" }, "aiohttp-retry": { "hashes": [ - "sha256:7661af92471e9a96c69d9b8f32021360272073397e6a15bc44c1726b12f46056", - "sha256:92c47f1580040208bac95d9a8389a87227ef22758530f2e3f4683395e42c41b5" + "sha256:3aeeead8f6afe48272db93ced9440cf4eda8b6fd7ee2abb25357b7eb28525b45", + "sha256:9a8e637e31682ad36e1ff9f8bcba912fcfc7d7041722bc901a4b948da4d71ea9" ], "markers": "python_version >= '3.7'", - "version": "==2.9.0" + "version": "==2.8.3" }, "aiosignal": { "hashes": [ - "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", - "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" + "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", + "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54" ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "markers": "python_version >= '3.9'", + "version": "==1.3.2" }, "amqp": { "hashes": [ - "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637", - "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd" + "sha256:43b3319e1b4e7d1251833a93d672b4af1e40f3d632d479b98661a95f117880a2", + "sha256:cddc00c725449522023bad949f70fff7b48f0b1ade74d170a6f10ab044739432" ], "markers": "python_version >= '3.6'", - "version": "==5.2.0" + "version": "==5.3.1" }, "annotated-types": { "hashes": [ @@ -182,11 +167,11 @@ }, "anyio": { "hashes": [ - "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", - "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d" + "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48", + "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352" ], "markers": "python_version >= '3.9'", - "version": "==4.6.2.post1" + "version": "==4.7.0" }, "asgiref": { "hashes": [ @@ -205,20 +190,20 @@ }, "async-timeout": { "hashes": [ - "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", - "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" + "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", + "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==4.0.3" + "markers": "python_version >= '3.8'", + "version": "==5.0.1" }, "attrs": { "hashes": [ - "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", - "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" + "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", + "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308" ], - "markers": "python_version >= '3.7'", - "version": "==24.2.0" + "markers": "python_version >= '3.8'", + "version": "==24.3.0" }, "autobahn": { "hashes": [ @@ -414,11 +399,11 @@ "django" ], "hashes": [ - "sha256:5d02ead62715ab4061cd3b07562db898a976badc274d88743e6f00f6e3093e98", - "sha256:ad7a213739531a4493a5ea8190ad4752c42f228f47d86940133d7f63b168a299" + "sha256:bd4a543ea060a938ee3194777d73b5596cee476840646d6403cb2e13c0618e0e", + "sha256:de01f4d074934c48ff4101051c3bc1905d46f99129851206f176d89e7df6a113" ], "markers": "python_version >= '3.11'", - "version": "==1.1.1" + "version": "==1.2.0" }, "celery": { "hashes": [ @@ -434,20 +419,20 @@ "django" ], "hashes": [ - "sha256:6a153da3005c8044e8550d45791ad6e5a2b56471db4b660deb215a140c97c999", - "sha256:bc24475f625bc0ddcd2d3ba115742353aada611710d63c8436ff4b5351cd8470" + "sha256:7628328e99b7654467afdbd4830480f284a621bd9ee3e3165002a0e7e793f03d", + "sha256:8bdbac8707ac5f23c2a6da655baca5e5920bbf2b2f0985e01d9c51569503c4a4" ], "markers": "python_version >= '3.11'", - "version": "==1.8.0" + "version": "==1.9.0" }, "certifi": { "hashes": [ - "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", + "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==2024.8.30" + "version": "==2024.12.14" }, "cffi": { "hashes": [ @@ -519,137 +504,124 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "channels": { "hashes": [ - "sha256:a3c4419307f582c3f71d67bfb6eff748ae819c2f360b9b141694d84f242baa48", - "sha256:e0ed375719f5c1851861f05ed4ce78b0166f9245ca0ecd836cb77d4bb531489d" + "sha256:6b75bc8d6888fb7236e7e7bf1948520b72d296ad08216a242fc56b1db0ffde1a", + "sha256:d9e707487431ba5dbce9af982970dab3b0efd786580fadb99e45dca5e39fdd59" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "channels-redis": { "hashes": [ - "sha256:01c26c4d5d3a203f104bba9e5585c0305a70df390d21792386586068162027fd", - "sha256:2c5b944a39bd984b72aa8005a3ae11637bf29b5092adeb91c9aad4ab819a8ac4" + "sha256:2ca33105b3a04b5a327a9c47dd762b546f30b76a0cd3f3f593a23d91d346b6f4", + "sha256:8375e81493e684792efe6e6eca60ef3d7782ef76c6664057d2e5c31e80d636dd" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==4.2.0" + "version": "==4.2.1" }, "charset-normalizer": { "hashes": [ - "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", - "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", - "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", - "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", - "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", - "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", - "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", - "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", - "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", - "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", - "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", - "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", - "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", - "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", - "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", - "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", - "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", - "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", - "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", - "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", - "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", - "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", - "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", - "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", - "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", - "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", - "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", - "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", - "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", - "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", - "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", - "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", - "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", - "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", - "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", - "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", - "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", - "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", - "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", - "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", - "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", - "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", - "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", - "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", - "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", - "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", - "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", - "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", - "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", - "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", - "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", - "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", - "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", - "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", - "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", - "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", - "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", - "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", - "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", - "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", - "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", - "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", - "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", - "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", - "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", - "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", - "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", - "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", - "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", - "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", - "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", - "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", - "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", - "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", - "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", - "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", - "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", - "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", - "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", - "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", - "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", - "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", - "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", - "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", - "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", - "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", - "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", - "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", - "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", - "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", - "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", - "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", - "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", - "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", - "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", - "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", - "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", - "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", - "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", - "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", - "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", - "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", - "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", - "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", - "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.4.0" + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "circuitbreaker": { "hashes": [ @@ -661,11 +633,11 @@ }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", + "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.8" }, "click-didyoumean": { "hashes": [ @@ -718,37 +690,37 @@ }, "cryptography": { "hashes": [ - "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362", - "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", - "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa", - "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83", - "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff", - "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", - "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", - "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664", - "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08", - "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", - "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", - "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", - "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", - "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", - "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", - "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", - "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3", - "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", - "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", - "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2", - "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c", - "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995", - "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", - "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", - "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7", - "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd", - "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7" + "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", + "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731", + "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", + "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", + "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", + "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", + "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", + "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", + "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", + "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", + "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", + "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c", + "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", + "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", + "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", + "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", + "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa", + "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", + "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", + "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", + "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", + "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", + "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", + "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", + "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", + "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756", + "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==43.0.3" + "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", + "version": "==44.0.0" }, "cssselect": { "hashes": [ @@ -794,11 +766,11 @@ }, "deprecated": { "hashes": [ - "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", - "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3" + "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320", + "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.2.14" + "version": "==1.2.15" }, "distro": { "hashes": [ @@ -818,12 +790,12 @@ }, "django": { "hashes": [ - "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0", - "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed" + "sha256:236e023f021f5ce7dee5779de7b286565fdea5f4ab86bae5338e3f7b69896cf0", + "sha256:de450c09e91879fa5a307f696e57c851955c910a438a35e6b4c895e86bedc82a" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==5.1.2" + "version": "==5.1.4" }, "django-appconf": { "hashes": [ @@ -952,12 +924,12 @@ }, "eventlet": { "hashes": [ - "sha256:801ac231401e41f33a799457c78fdbfabc1c2f28bf9346d4ec4188e9aebc2067", - "sha256:fa49bf5a549cdbaa06919679979ea022ac8f8f3cf0499f26849a1cd8e64c30b1" + "sha256:4a2e3cbc53917c8f39074ccf689501168563d3a4df59e9cddd5e9d3b7f85c599", + "sha256:6a46823af1dca7d29cf04c0d680365805435473c3acbffc176765c7f8787edac" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.37.0" + "version": "==0.38.2" }, "exceptiongroup": { "hashes": [ @@ -985,10 +957,10 @@ }, "fastjsonschema": { "hashes": [ - "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23", - "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a" + "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", + "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667" ], - "version": "==2.20.0" + "version": "==2.21.1" }, "frozenlist": { "hashes": [ @@ -1090,85 +1062,85 @@ }, "gevent": { "hashes": [ - "sha256:051b22e2758accfddb0457728bfc9abf8c3f2ce6bca43f1ff6e07b5ed9e49bf4", - "sha256:0de6eb3d55c03138fda567d9bfed28487ce5d0928c5107549767a93efdf2be26", - "sha256:18e6984ec96fc95fd67488555c38ece3015be1f38b1bcceb27b7d6c36b343008", - "sha256:1c3a828b033fb02b7c31da4d75014a1f82e6c072fc0523456569a57f8b025861", - "sha256:1ce6dab94c0b0d24425ba55712de2f8c9cb21267150ca63f5bb3a0e1f165da99", - "sha256:1e24ffea72e27987979c009536fd0868e52239b44afe6cf7135ce8aafd0f108e", - "sha256:26ca7a6b42d35129617025ac801135118333cad75856ffc3217b38e707383eba", - "sha256:34aea15f9c79f27a8faeaa361bc1e72c773a9b54a1996a2ec4eefc8bcd59a824", - "sha256:385710355eadecdb70428a5ae3e7e5a45dcf888baa1426884588be9d25ac4290", - "sha256:3ac83b74304487afa211a01909c7dd257e574db0cd429d866c298e21df7aeedf", - "sha256:3ad8fb70aa0ebc935729c9699ac31b210a49b689a7b27b7ac9f91676475f3f53", - "sha256:40ea3e40e8bb4fdb143c2a8edf2ccfdebd56016c7317c341ce8094c7bee08818", - "sha256:57a5c4e0bdac482c5f02f240d0354e61362df73501ef6ebafce8ef635cad7527", - "sha256:5d850a453d66336272be4f1d3a8126777f3efdaea62d053b4829857f91e09755", - "sha256:68c3a0d8402755eba7f69022e42e8021192a721ca8341908acc222ea597029b6", - "sha256:7021e26d70189b33c27173d4173f27bf4685d6b6f1c0ea50e5335f8491cb110c", - "sha256:70e9ed7ecb70e0df7dc97c3bc420de9a45a7c76bd5861c6cfec8c549700e681e", - "sha256:89c4115e3f5ada55f92b61701a46043fe42f702b5af863b029e4c1a76f6cc2d4", - "sha256:8af65a4d4feaec6042c666d22c322a310fba3b47e841ad52f724b9c3ce5da48e", - "sha256:8e58ee3723f1fbe07d66892f1caa7481c306f653a6829b6fd16cb23d618a5915", - "sha256:9ca2266e08f43c0e22c028801dff7d92a0b102ef20e4caeb6a46abfb95f6a328", - "sha256:9e1210334a9bc9f76c3d008e0785ca62214f8a54e1325f6c2ecab3b6a572a015", - "sha256:a9a89d6e396ef6f1e3968521bf56e8c4bee25b193bbf5d428b7782d582410822", - "sha256:aa7ee1bd5cabb2b7ef35105f863b386c8d5e332f754b60cfc354148bd70d35d1", - "sha256:b52382124eca13135a3abe4f65c6bd428656975980a48e51b17aeab68bdb14db", - "sha256:c1d80090485da1ea3d99205fe97908b31188c1f4857f08b333ffaf2de2e89d18", - "sha256:ce417bcaaab496bc9c77f75566531e9d93816262037b8b2dbb88b0fdcd66587c", - "sha256:d67daed8383326dc8b5e58d88e148d29b6b52274a489e383530b0969ae7b9cb9", - "sha256:d758f0d4dbf32502ec87bb9b536ca8055090a16f8305f0ada3ce6f34e70f2fd7", - "sha256:d7a1ad0f2da582f5bd238bca067e1c6c482c30c15a6e4d14aaa3215cbb2232f3", - "sha256:e534e6a968d74463b11de6c9c67f4b4bf61775fb00f2e6e0f7fcdd412ceade18", - "sha256:eb5edb6433764119a664bbb148d2aea9990950aa89cc3498f475c2408d523ea3", - "sha256:f0c129f81d60cda614acb4b0c5731997ca05b031fb406fcb58ad53a7ade53b13", - "sha256:f147e38423fbe96e8731f60a63475b3d2cab2f3d10578d8ee9d10c507c58a2ff", - "sha256:f18689f7a70d2ed0e75bad5036ec3c89690a493d4cfac8d7cdb258ac04b132bd", - "sha256:f2ae3efbbd120cdf4a68b7abc27a37e61e6f443c5a06ec2c6ad94c37cd8471ec", - "sha256:f4e526fdc279c655c1e809b0c34b45844182c2a6b219802da5e411bd2cf5a8ad", - "sha256:f7f4f171d4d2018170454d84c934842e1b5f6ce7468ba298f6e7f7cff15000a3" + "sha256:1c3443b0ed23dcb7c36a748d42587168672953d368f2956b17fad36d43b58836", + "sha256:1d4fadc319b13ef0a3c44d2792f7918cf1bca27cacd4d41431c22e6b46668026", + "sha256:1ea50009ecb7f1327347c37e9eb6561bdbc7de290769ee1404107b9a9cba7cf1", + "sha256:2142704c2adce9cd92f6600f371afb2860a446bfd0be5bd86cca5b3e12130766", + "sha256:351d1c0e4ef2b618ace74c91b9b28b3eaa0dd45141878a964e03c7873af09f62", + "sha256:356b73d52a227d3313f8f828025b665deada57a43d02b1cf54e5d39028dbcf8d", + "sha256:3d882faa24f347f761f934786dde6c73aa6c9187ee710189f12dcc3a63ed4a50", + "sha256:58851f23c4bdb70390f10fc020c973ffcf409eb1664086792c8b1e20f25eef43", + "sha256:68bee86b6e1c041a187347ef84cf03a792f0b6c7238378bf6ba4118af11feaae", + "sha256:7398c629d43b1b6fd785db8ebd46c0a353880a6fab03d1cf9b6788e7240ee32e", + "sha256:816b3883fa6842c1cf9d2786722014a0fd31b6312cca1f749890b9803000bad6", + "sha256:81d918e952954675f93fb39001da02113ec4d5f4921bf5a0cc29719af6824e5d", + "sha256:85329d556aaedced90a993226d7d1186a539c843100d393f2349b28c55131c85", + "sha256:8619d5c888cb7aebf9aec6703e410620ef5ad48cdc2d813dd606f8aa7ace675f", + "sha256:8bd1419114e9e4a3ed33a5bad766afff9a3cf765cb440a582a1b3a9bc80c1aca", + "sha256:92e0d7759de2450a501effd99374256b26359e801b2d8bf3eedd3751973e87f5", + "sha256:92fe5dfee4e671c74ffaa431fd7ffd0ebb4b339363d24d0d944de532409b935e", + "sha256:97e2f3999a5c0656f42065d02939d64fffaf55861f7d62b0107a08f52c984897", + "sha256:9d3b249e4e1f40c598ab8393fc01ae6a3b4d51fc1adae56d9ba5b315f6b2d758", + "sha256:a3d75fa387b69c751a3d7c5c3ce7092a171555126e136c1d21ecd8b50c7a6e46", + "sha256:a5f1701ce0f7832f333dd2faf624484cbac99e60656bfbb72504decd42970f0f", + "sha256:b24d800328c39456534e3bc3e1684a28747729082684634789c2f5a8febe7671", + "sha256:b5efe72e99b7243e222ba0c2c2ce9618d7d36644c166d63373af239da1036bab", + "sha256:b7bfcfe08d038e1fa6de458891bca65c1ada6d145474274285822896a858c870", + "sha256:beede1d1cff0c6fafae3ab58a0c470d7526196ef4cd6cc18e7769f207f2ea4eb", + "sha256:c6b775381f805ff5faf250e3a07c0819529571d19bb2a9d474bee8c3f90d66af", + "sha256:c9c935b83d40c748b6421625465b7308d87c7b3717275acd587eef2bd1c39546", + "sha256:ca845138965c8c56d1550499d6b923eb1a2331acfa9e13b817ad8305dde83d11", + "sha256:d618e118fdb7af1d6c1a96597a5cd6ac84a9f3732b5be8515c6a66e098d498b6", + "sha256:d6c0a065e31ef04658f799215dddae8752d636de2bed61365c358f9c91e7af61", + "sha256:d740206e69dfdfdcd34510c20adcb9777ce2cc18973b3441ab9767cd8948ca8a", + "sha256:d7886b63ebfb865178ab28784accd32f287d5349b3ed71094c86e4d3ca738af5", + "sha256:d9347690f4e53de2c4af74e62d6fabc940b6d4a6cad555b5a379f61e7d3f2a8e", + "sha256:d9ca80711e6553880974898d99357fb649e062f9058418a92120ca06c18c3c59", + "sha256:e24181d172f50097ac8fc272c8c5b030149b630df02d1c639ee9f878a470ba2b", + "sha256:ec68e270543ecd532c4c1d70fca020f90aa5486ad49c4f3b8b2e64a66f5c9274", + "sha256:f43f47e702d0c8e1b8b997c00f1601486f9f976f84ab704f8f11536e3fa144c9", + "sha256:ff96c5739834c9a594db0e12bf59cb3fa0e5102fc7b893972118a3166733d61c" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==24.10.3" + "version": "==24.11.1" }, "google-api-core": { "extras": [ "grpc" ], "hashes": [ - "sha256:26f8d76b96477db42b55fd02a33aae4a42ec8b86b98b94969b7333a2c828bf35", - "sha256:a6652b6bd51303902494998626653671703c420f6f4c88cfd3f50ed723e9d021" + "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9", + "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf" ], "markers": "python_version >= '3.7'", - "version": "==2.22.0" + "version": "==2.24.0" }, "google-api-python-client": { "hashes": [ - "sha256:1a5232e9cfed8c201799d9327e4d44dc7ea7daa3c6e1627fca41aa201539c0da", - "sha256:b9d68c6b14ec72580d66001bd33c5816b78e2134b93ccc5cf8f624516b561750" + "sha256:6352185c505e1f311f11b0b96c1b636dcb0fec82cd04b80ac5a671ac4dcab339", + "sha256:b809c111ded61716a9c1c7936e6899053f13bae3defcdfda904bd2ca68065b9c" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.149.0" + "version": "==2.156.0" }, "google-apps-meet": { "hashes": [ - "sha256:282e6c3c8aa49f4a34a6b2ee31c94720801adf200777c7a08f491736de45e4ba", - "sha256:3125f4f8dcdb78f4973a02653540ce6c8c19c4369e2cbed731b7a9f1cbe41d1d" + "sha256:a9c811b7bac7568dea5622ba44005f6bca9ae5d928a68b6f22cd9b8cbc354f74", + "sha256:bfb91f816d679278c80fc079be4cbe3b2f736106697b709a9398d080959730d0" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.1.9" + "version": "==0.1.11" }, "google-auth": { "hashes": [ - "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f", - "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a" + "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00", + "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0" ], "markers": "python_version >= '3.7'", - "version": "==2.35.0" + "version": "==2.37.0" }, "google-auth-httplib2": { "hashes": [ @@ -1189,12 +1161,12 @@ }, "google-cloud-bigquery": { "hashes": [ - "sha256:e0e9ad28afa67a18696e624cbccab284bf2c0a3f6eeb9eeb0426c69b943793a8", - "sha256:edbdc788beea659e04c0af7fe4dcd6d9155344b98951a0d5055bd2f15da4ba23" + "sha256:379c524054d7b090fa56d0c22662cc6e6458a6229b6754c0e7177e3a73421d2c", + "sha256:b53b0431e5ba362976a4cd8acce72194b4116cdf8115030c7b339b884603fcc3" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==3.26.0" + "version": "==3.27.0" }, "google-cloud-bigquery-storage": { "hashes": [ @@ -1213,12 +1185,12 @@ }, "google-cloud-datastore": { "hashes": [ - "sha256:07950b9c8865087c565f45fa3fdd7a05d4c3d99adf79e10c3f596ff08a7d9bba", - "sha256:b9383af24d8e90ed6c5d161d72411d82efd9b21c051fa6f4bbd743a49d37ffb3" + "sha256:9665d009729d9551329d9476f4d5bda9c11d3469243ea8a2c0d9490b65aa899f", + "sha256:d2190180343b807d4aa3b0b3bb837606349b71e5e74e29aa9009c0ae38c0b6a0" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.20.1" + "version": "==2.20.2" }, "google-cloud-firestore": { "hashes": [ @@ -1240,21 +1212,21 @@ }, "google-cloud-recaptcha-enterprise": { "hashes": [ - "sha256:169aeae9982d6c85b27caff228ae3ec66dd955ce2e80bb3d3fcf9f842a2b7696", - "sha256:651a1179f9ffa5ab6b519e693b1f808d5058681183273395b534a17575cb3592" + "sha256:00a5eeebd156db219afb92db5d311e6fda95b1927630ea95f569b89df44b9ceb", + "sha256:9192497490daffb6f317293fdb21c09b4b340b0bc0eeb19f5b9c0ea57527caf0" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.23.0" + "version": "==1.26.0" }, "google-cloud-storage": { "hashes": [ - "sha256:97a4d45c368b7d401ed48c4fdfe86e1e1cb96401c9e199e419d289e2c0370166", - "sha256:aaf7acd70cdad9f274d29332673fcab98708d0e1f4dceb5a5356aaef06af4d99" + "sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba", + "sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.18.2" + "version": "==2.19.0" }, "google-crc32c": { "hashes": [ @@ -1299,18 +1271,18 @@ }, "googleapis-common-protos": { "hashes": [ - "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63", - "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0" + "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c", + "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed" ], "markers": "python_version >= '3.7'", - "version": "==1.65.0" + "version": "==1.66.0" }, "graphene": { "hashes": [ - "sha256:828a8d7b1bce450566a72cc8733716c20f3acfc659960de73dd38f46dc302040", - "sha256:ca98f853201293871cdc7f55faf2523a9bc077181fe0f4947db5a243e5c67083" + "sha256:2a3786948ce75fe7e078443d37f609cbe5bb36ad8d6b828740ad3b95ed1a0aaa", + "sha256:820db6289754c181007a150db1f7fff544b94142b556d12e3ebc777a7bf36c71" ], - "version": "==3.4.1" + "version": "==3.4.3" }, "graphene-django": { "hashes": [ @@ -1420,75 +1392,77 @@ "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", "sha256:f6ff3b14f2df4c41660a7dec01045a045653998784bf8cfcb5a525bdffffbc8f" ], - "markers": "platform_python_implementation == 'CPython'", + "markers": "python_version >= '3.7'", "version": "==3.1.1" }, "grpcio": { "hashes": [ - "sha256:01f616a964e540638af5130469451cf580ba8c7329f45ca998ab66e0c7dcdb04", - "sha256:0489063974d1452436139501bf6b180f63d4977223ee87488fe36858c5725292", - "sha256:0e6f255980afef598a9e64a24efce87b625e3e3c80a45162d111a461a9f92955", - "sha256:0f3e49c738396e93b7ba9016e153eb09e0778e776df6090c1b8c91877cc1c426", - "sha256:178f5db771c4f9a9facb2ab37a434c46cb9be1a75e820f187ee3d1e7805c4f65", - "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970", - "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e", - "sha256:24e8a26dbfc5274d7474c27759b54486b8de23c709d76695237515bc8b5baeab", - "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953", - "sha256:299b3d8c4f790c6bcca485f9963b4846dd92cf6f1b65d3697145d005c80f9fe8", - "sha256:3b6c16489326d79ead41689c4b84bc40d522c9a7617219f4ad94bc7f448c5085", - "sha256:3dc2ed4cabea4dc14d5e708c2b426205956077cc5de419b4d4079315017e9732", - "sha256:43112046864317498a33bdc4797ae6a268c36345a910de9b9c17159d8346602f", - "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af", - "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78", - "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc", - "sha256:5db70d32d6703b89912af16d6d45d78406374a8b8ef0d28140351dd0ec610e98", - "sha256:5ed601c4c6008429e3d247ddb367fe8c7259c355757448d7c1ef7bd4a6739e8e", - "sha256:60336bff760fbb47d7e86165408126f1dded184448e9a4c892189eb7c9d3f90f", - "sha256:608d87d1bdabf9e2868b12338cd38a79969eaf920c89d698ead08f48de9c0f9e", - "sha256:60e6a4dcf5af7bbc36fd9f81c9f372e8ae580870a9e4b6eafe948cd334b81cf3", - "sha256:638354e698fd0c6c76b04540a850bf1db27b4d2515a19fcd5cf645c48d3eb1ed", - "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38", - "sha256:7818c0454027ae3384235a65210bbf5464bd715450e30a3d40385453a85a70cb", - "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5", - "sha256:804c6457c3cd3ec04fe6006c739579b8d35c86ae3298ffca8de57b493524b771", - "sha256:80b866f73224b0634f4312a4674c1be21b2b4afa73cb20953cbbb73a6b36c3cc", - "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb", - "sha256:85f862069b86a305497e74d0dc43c02de3d1d184fc2c180993aa8aa86fbd19b8", - "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75", - "sha256:8a23cbcc5bb11ea7dc6163078be36c065db68d915c24f5faa4f872c573bb400f", - "sha256:8b0341d66a57f8a3119b77ab32207072be60c9bf79760fa609c5609f2deb1f3f", - "sha256:917e8d8994eed1d86b907ba2a61b9f0aef27a2155bca6cbb322430fc7135b7bb", - "sha256:95b5f2b857856ed78d72da93cd7d09b6db8ef30102e5e7fe0961fe4d9f7d48e8", - "sha256:9e838cad2176ebd5d4a8bb03955138d6589ce9e2ce5d51c3ada34396dbd2dba8", - "sha256:9fd042de4a82e3e7aca44008ee2fb5da01b3e5adb316348c21980f7f58adc311", - "sha256:a25bdea92b13ff4d7790962190bf6bf5c4639876e01c0f3dda70fc2769616335", - "sha256:a6703916c43b1d468d0756c8077b12017a9fcb6a1ef13faf49e67d20d7ebda62", - "sha256:a93deda571a1bf94ec1f6fcda2872dad3ae538700d94dc283c672a3b508ba3af", - "sha256:aa0162e56fd10a5547fac8774c4899fc3e18c1aa4a4759d0ce2cd00d3696ea6b", - "sha256:b49359977c6ec9f5d0573ea4e0071ad278ef905aa74e420acc73fd28ce39e9ce", - "sha256:beee96c8c0b1a75d556fe57b92b58b4347c77a65781ee2ac749d550f2a365dc1", - "sha256:c7a01337407dd89005527623a4a72c5c8e2894d22bead0895306b23c6695698f", - "sha256:c9b929f13677b10f63124c1a410994a401cdd85214ad83ab67cc077fc7e480f0", - "sha256:cdc491ae35a13535fd9196acb5afe1af37c8237df2e54427be3eecda3653127e", - "sha256:e279330bef1744040db8fc432becc8a727b84f456ab62b744d3fdb83f327e121", - "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744", - "sha256:e7d1797a8a3845437d327145959a2c0c47c05947c9eef5ff1a4c80e499dcc6fa", - "sha256:ea33986b70f83844cd00814cee4451055cd8cab36f00ac64a31f5bb09b31919e", - "sha256:ec74ef02010186185de82cc594058a3ccd8d86821842bbac9873fd4a2cf8be8d", - "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0", - "sha256:f5a27dddefe0e2357d3e617b9079b4bfdc91341a91565111a21ed6ebbc51b22d", - "sha256:f5b76ff64aaac53fede0cc93abf57894ab2a7362986ba22243d06218b93efe46", - "sha256:f9fff78ba10d4250bfc07a01bd6254a6d87dc67f9627adece85c0b2ed754fa96", - "sha256:fa0c739ad8b1996bd24823950e3cb5152ae91fca1c09cc791190bf1627ffefba" - ], - "version": "==1.67.1" + "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43", + "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161", + "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e", + "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76", + "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf", + "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613", + "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600", + "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c", + "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5", + "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1", + "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515", + "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9", + "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c", + "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1", + "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0", + "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054", + "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73", + "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684", + "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d", + "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c", + "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1", + "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e", + "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172", + "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5", + "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2", + "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e", + "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded", + "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a", + "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666", + "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea", + "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63", + "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330", + "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60", + "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079", + "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f", + "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd", + "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c", + "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1", + "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385", + "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e", + "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9", + "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54", + "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad", + "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a", + "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe", + "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1", + "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d", + "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78", + "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0", + "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e", + "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475", + "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c", + "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746", + "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad", + "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9" + ], + "markers": "python_version >= '3.8'", + "version": "==1.68.1" }, "grpcio-status": { "hashes": [ - "sha256:16e6c085950bdacac97c779e6a502ea671232385e6e37f258884d6883392c2bd", - "sha256:2bf38395e028ceeecfd8866b081f61628114b384da7d51ae064ddc8d766a5d11" + "sha256:66f3d8847f665acfd56221333d66f7ad8927903d87242a482996bdb45e8d28fd", + "sha256:e1378d036c81a1610d7b4c7a146cd663dd13fcc915cf4d7d053929dba5bbb6e1" ], - "version": "==1.67.1" + "markers": "python_version >= '3.8'", + "version": "==1.68.1" }, "gunicorn": { "hashes": [ @@ -1516,104 +1490,119 @@ }, "hiredis": { "hashes": [ - "sha256:00018f22f38530768b73ea86c11f47e8d4df65facd4e562bd78773bd1baef35e", - "sha256:034925b5fb514f7b11aac38cd55b3fd7e9d3af23bd6497f3f20aa5b8ba58e232", - "sha256:038756db735e417ab36ee6fd7725ce412385ed2bd0767e8179a4755ea11b804f", - "sha256:04ccae6dcd9647eae6025425ab64edb4d79fde8b9e6e115ebfabc6830170e3b2", - "sha256:0aacc0a78e1d94d843a6d191f224a35893e6bdfeb77a4a89264155015c65f126", - "sha256:0bb6f9fd92f147ba11d338ef5c68af4fd2908739c09e51f186e1d90958c68cc1", - "sha256:0dcfa684966f25b335072115de2f920228a3c2caf79d4bfa2b30f6e4f674a948", - "sha256:100431e04d25a522ef2c3b94f294c4219c4de3bfc7d557b6253296145a144c11", - "sha256:120f2dda469b28d12ccff7c2230225162e174657b49cf4cd119db525414ae281", - "sha256:122171ff47d96ed8dd4bba6c0e41d8afaba3e8194949f7720431a62aa29d8895", - "sha256:13c275b483a052dd645eb2cb60d6380f1f5215e4c22d6207e17b86be6dd87ffa", - "sha256:13c345e7278c210317e77e1934b27b61394fee0dec2e8bd47e71570900f75823", - "sha256:1f669212c390eebfbe03c4e20181f5970b82c5d0a0ad1df1785f7ffbe7d61150", - "sha256:1fb8de899f0145d6c4d5d4bd0ee88a78eb980a7ffabd51e9889251b8f58f1785", - "sha256:204b79b30a0e6be0dc2301a4d385bb61472809f09c49f400497f1cdd5a165c66", - "sha256:22c17c96143c2a62dfd61b13803bc5de2ac526b8768d2141c018b965d0333b66", - "sha256:23142a8af92a13fc1e3f2ca1d940df3dcf2af1d176be41fe8d89e30a837a0b60", - "sha256:3d22c53f0ec5c18ecb3d92aa9420563b1c5d657d53f01356114978107b00b860", - "sha256:3dc8043959b50141df58ab4f398e8ae84c6f9e673a2c9407be65fc789138f4a6", - "sha256:3ea635101b739c12effd189cc19b2671c268abb03013fd1f6321ca29df3ca625", - "sha256:41afc0d3c18b59eb50970479a9c0e5544fb4b95e3a79cf2fbaece6ddefb926fe", - "sha256:4664dedcd5933364756d7251a7ea86d60246ccf73a2e00912872dacbfcef8978", - "sha256:466f836dbcf86de3f9692097a7a01533dc9926986022c6617dc364a402b265c5", - "sha256:467d28112c7faa29b7db743f40803d927c8591e9da02b6ce3d5fadc170a542a2", - "sha256:47de0bbccf4c8a9f99d82d225f7672b9dd690d8fd872007b933ef51a302c9fa6", - "sha256:484025d2eb8f6348f7876fc5a2ee742f568915039fcb31b478fd5c242bb0fe3a", - "sha256:48727d7d405d03977d01885f317328dc21d639096308de126c2c4e9950cbd3c9", - "sha256:4b182791c41c5eb1d9ed736f0ff81694b06937ca14b0d4dadde5dadba7ff6dae", - "sha256:4c6efcbb5687cf8d2aedcc2c3ed4ac6feae90b8547427d417111194873b66b06", - "sha256:4ea3a86405baa8eb0d3639ced6926ad03e07113de54cb00fd7510cb0db76a89d", - "sha256:50a196af0ce657fcde9bf8a0bbe1032e22c64d8fcec2bc926a35e7ff68b3a166", - "sha256:50da7a9edf371441dfcc56288d790985ee9840d982750580710a9789b8f4a290", - "sha256:51b99cfac514173d7b8abdfe10338193e8a0eccdfe1870b646009d2fb7cbe4b5", - "sha256:54a6dd7b478e6eb01ce15b3bb5bf771e108c6c148315bf194eb2ab776a3cac4d", - "sha256:562eaf820de045eb487afaa37e6293fe7eceb5b25e158b5a1974b7e40bf04543", - "sha256:5a8dffb5f5b3415a4669d25de48b617fd9d44b0bccfc4c2ab24b06406ecc9ecb", - "sha256:5b5cff42a522a0d81c2ae7eae5e56d0ee7365e0c4ad50c4de467d8957aff4414", - "sha256:63482db3fadebadc1d01ad33afa6045ebe2ea528eb77ccaabd33ee7d9c2bad48", - "sha256:6ca41fa40fa019cde42c21add74aadd775e71458051a15a352eabeb12eb4d084", - "sha256:6eecb343c70629f5af55a8b3e53264e44fa04e155ef7989de13668a0cb102a90", - "sha256:719c32147ba29528cb451f037bf837dcdda4ff3ddb6cdb12c4216b0973174718", - "sha256:77c8006c12154c37691b24ff293c077300c22944018c3ff70094a33e10c1d795", - "sha256:793c80a3d6b0b0e8196a2d5de37a08330125668c8012922685e17aa9108c33ac", - "sha256:7d99b91e42217d7b4b63354b15b41ce960e27d216783e04c4a350224d55842a4", - "sha256:82f794d564f4bc76b80c50b03267fe5d6589e93f08e66b7a2f674faa2fa76ebc", - "sha256:83a29cc7b21b746cb6a480189e49f49b2072812c445e66a9e38d2004d496b81c", - "sha256:869f6d5537d243080f44253491bb30aa1ec3c21754003b3bddeadedeb65842b0", - "sha256:8854969e7480e8d61ed7549eb232d95082a743e94138d98d7222ba4e9f7ecacd", - "sha256:898636a06d9bf575d2c594129085ad6b713414038276a4bfc5db7646b8a5be78", - "sha256:8e0bb6102ebe2efecf8a3292c6660a0e6fac98176af6de67f020bea1c2343717", - "sha256:8fed69bbaa307040c62195a269f82fc3edf46b510a17abb6b30a15d7dab548df", - "sha256:9862db92ef67a8a02e0d5370f07d380e14577ecb281b79720e0d7a89aedb9ee5", - "sha256:98a152052b8878e5e43a2e3a14075218adafc759547c98668a21e9485882696c", - "sha256:99516d99316062824a24d145d694f5b0d030c80da693ea6f8c4ecf71a251d8bb", - "sha256:9b285ef6bf1581310b0d5e8f6ce64f790a1c40e89c660e1320b35f7515433672", - "sha256:a131377493a59fb0f5eaeb2afd49c6540cafcfba5b0b3752bed707be9e7c4eaf", - "sha256:a1c81c89ed765198da27412aa21478f30d54ef69bf5e4480089d9c3f77b8f882", - "sha256:a2537b2cd98192323fce4244c8edbf11f3cac548a9d633dbbb12b48702f379f4", - "sha256:a41be8af1fd78ca97bc948d789a09b730d1e7587d07ca53af05758f31f4b985d", - "sha256:a631e2990b8be23178f655cae8ac6c7422af478c420dd54e25f2e26c29e766f1", - "sha256:a6a49ef161739f8018c69b371528bdb47d7342edfdee9ddc75a4d8caddf45a6e", - "sha256:ac6d929cb33dd12ad3424b75725975f0a54b5b12dbff95f2a2d660c510aa106d", - "sha256:b23291951959141173eec10f8573538e9349fa27f47a0c34323d1970bf891ee5", - "sha256:ba9fc605ac558f0de67463fb588722878641e6fa1dabcda979e8e69ff581d0bd", - "sha256:bdc144d56333c52c853c31b4e2e52cfbdb22d3da4374c00f5f3d67c42158970f", - "sha256:c073848d2b1d5561f3903879ccf4e1a70c9b1e7566c7bdcc98d082fa3e7f0a1d", - "sha256:c1018cc7f12824506f165027eabb302735b49e63af73eb4d5450c66c88f47026", - "sha256:c3ece960008dab66c6b8bb3a1350764677ee7c74ccd6270aaf1b1caf9ccebb46", - "sha256:c3fdad75e7837a475900a1d3a5cc09aa024293c3b0605155da2d42f41bc0e482", - "sha256:c8a1df39d74ec507d79c7a82c8063eee60bf80537cdeee652f576059b9cdd15c", - "sha256:c8a91e9520fbc65a799943e5c970ffbcd67905744d8becf2e75f9f0a5e8414f0", - "sha256:d10fcd9e0eeab835f492832b2a6edb5940e2f1230155f33006a8dfd3bd2c94e4", - "sha256:d435ae89073d7cd51e6b6bf78369c412216261c9c01662e7008ff00978153729", - "sha256:d7a4c1791d7aa7e192f60fe028ae409f18ccdd540f8b1e6aeb0df7816c77e4a4", - "sha256:dc384874a719c767b50a30750f937af18842ee5e288afba95a5a3ed703b1515a", - "sha256:df274e3abb4df40f4c7274dd3e587dfbb25691826c948bc98d5fead019dfb001", - "sha256:e069967cbd5e1900aafc4b5943888f6d34937fc59bf8918a1a546cb729b4b1e4", - "sha256:e194a0d5df9456995d8f510eab9f529213e7326af6b94770abf8f8b7952ddcaa", - "sha256:e1a9c14ae9573d172dc050a6f63a644457df5d01ec4d35a6a0f097f812930f83", - "sha256:e241fab6332e8fb5f14af00a4a9c6aefa22f19a336c069b7ddbf28ef8341e8d6", - "sha256:e421ac9e4b5efc11705a0d5149e641d4defdc07077f748667f359e60dc904420", - "sha256:e43679eca508ba8240d016d8cca9d27342d70184773c15bea78a23c87a1922f1", - "sha256:e584fe5f4e6681d8762982be055f1534e0170f6308a7a90f58d737bab12ff6a8", - "sha256:f114a6c86edbf17554672b050cce72abf489fe58d583c7921904d5f1c9691605", - "sha256:f2f312eef8aafc2255e3585dcf94d5da116c43ef837db91db9ecdc1bc930072d", - "sha256:f359175197fd833c8dd7a8c288f1516be45415bb5c939862ab60c2918e1e1943", - "sha256:f75999ae00a920f7dce6ecae76fa5e8674a3110e5a75f12c7a2c75ae1af53396", - "sha256:f91456507427ba36fd81b2ca11053a8e112c775325acc74e993201ea912d63e9", - "sha256:fa1fcad89d8a41d8dc10b1e54951ec1e161deabd84ed5a2c95c3c7213bdb3514", - "sha256:fa86bf9a0ed339ec9e8a9a9d0ae4dccd8671625c83f9f9f2640729b15e07fbfd", - "sha256:fcdb552ffd97151dab8e7bc3ab556dfa1512556b48a367db94b5c20253a35ee1", - "sha256:fcecbd39bd42cef905c0b51c9689c39d0cc8b88b1671e7f40d4fb213423aef3a", - "sha256:fe91d62b0594db5ea7d23fc2192182b1a7b6973f628a9b8b2e0a42a2be721ac6", - "sha256:fed8581ae26345dea1f1e0d1a96e05041a727a45e7d8d459164583e23c6ac441" + "sha256:0322d70f3328b97da14b6e98b18f0090a12ed8a8bf7ae20932e2eb9d1bb0aa2c", + "sha256:0614e16339f1784df3bbd2800322e20b4127d3f3a3509f00a5562efddb2521aa", + "sha256:072c162260ebb1d892683107da22d0d5da7a1414739eae4e185cac22fe89627f", + "sha256:07ab990d0835f36bf358dbb84db4541ac0a8f533128ec09af8f80a576eef2e88", + "sha256:09e89e7d34cfe5ca8f7a869fca827d1af0afe8aaddb26b38c01058730edb79ad", + "sha256:0f8ca13e2476ffd6d5be4763f5868133506ddcfa5ce54b4dac231ebdc19be6c6", + "sha256:0ffa2552f704a45954627697a378fc2f559004e53055b82f00daf30bd4305330", + "sha256:107b66ce977bb2dff8f2239e68344360a75d05fed3d9fa0570ac4d3020ce2396", + "sha256:1110eae007f30e70a058d743e369c24430327cd01fd97d99519d6794a58dd587", + "sha256:13f5b16f97d0bbd1c04ce367c49097d1214d60e11f9fee7ef2a9b54e0a6645c8", + "sha256:18e703ff860c1d83abbcf57012b309ead02b56b60e85150c6c3bfb37cbb16ebf", + "sha256:1c22fa74ddd063396b19fe8445a1ae8b4190eff755d5750dda48e860a45b2ee7", + "sha256:2102a94063d878c40df92f55199637a74f535e3a0b79ceba4a00538853a21be3", + "sha256:230dd0e77cb0f525f58a1306a7b4aaf078037fc5229110922332ca46f90821bb", + "sha256:2892db9db21f0cf7cc298d09f85d3e1f6dc4c4c24463ab67f79bc7a006d51867", + "sha256:2af62070aa9433802cae7be7364d5e82f76462c6a2ae34e53008b637aaa9a156", + "sha256:2e04c7feb9467e3170cd4d5bee381775783d81bbc45d6147c1c0ce3b50dc04f9", + "sha256:3004ef7436feb7bfa61c0b36d422b8fb8c29aaa1a514c9405f0fdee5e9694dd3", + "sha256:34d25aa25c10f966d5415795ed271da84605044dbf436c054966cea5442451b3", + "sha256:34f3f5f0354db2d6797a6fb08d2c036a50af62a1d919d122c1c784304ef49347", + "sha256:35b5fc061c8a0dbfdb440053280504d6aaa8d9726bd4d1d0e1cfcbbdf0d60b73", + "sha256:363e21fba55e1a26349dc9ca7da6b14332123879b6359bcee4a9acecb40ca33b", + "sha256:37aed4aa9348600145e2d019c7be27855e503ecc4906c6976ff2f3b52e3d5d97", + "sha256:39efab176fca3d5111075f6ba56cd864f18db46d858289d39360c5672e0e5c3e", + "sha256:3b5bd8adfe8742e331a94cccd782bffea251fa70d9a709e71f4510f50794d700", + "sha256:3dbf9163296fa45fbddcfc4c5900f10e9ddadda37117dbfb641e327e536b53e0", + "sha256:3e9445b7f117a9c8c8ccad97cb44daa55ddccff3cbc9079984eac56d982ba01f", + "sha256:4180dc5f646b426e5fa1212e1348c167ee2a864b3a70d56579163d64a847dd1e", + "sha256:4663a319ab7d22c597b9421e5ea384fd583e044f2f1ca9a1b98d4fef8a0fea2f", + "sha256:4a018340c073cf88cb635b2bedff96619df2f666018c655e7911f46fa2c1c178", + "sha256:4ef5ad8b91530e4d10a68562b0a380ea22705a60e88cecee086d7c63a38564ce", + "sha256:4f12018e5c5f866a1c3f7017cb2d88e5c6f9440df2281e48865a2b6c40f247f4", + "sha256:511e36a6fa41d3efab3cd5cd70ac388ed825993b9e66fa3b0e47cf27a2f5ffee", + "sha256:51d40ac3611091020d7dea6b05ed62cb152bff595fa4f931e7b6479d777acf7c", + "sha256:539e5bb725b62b76a5319a4e68fc7085f01349abc2316ef3df608ea0883c51d2", + "sha256:570cbf31413c77fe5e7c157f2943ca4400493ddd9cf2184731cfcafc753becd7", + "sha256:59a9230f3aa38a33d09d8171400de202f575d7a38869e5ce2947829bca6fe359", + "sha256:5c54a88eb9d8ebc4e5eefaadbe2102a4f7499f9e413654172f40aefd25350959", + "sha256:5ce71a797b5bc02c51da082428c00251ed6a7a67a03acbda5fbf9e8d028725f6", + "sha256:676b3d88674134bfaaf70dac181d1790b0f33b3187bfb9da9221e17e0e624f83", + "sha256:6c840b9cec086328f2ee2cfee0038b5d6bbb514bac7b5e579da6e346eaac056c", + "sha256:72a98ccc7b8ec9ce0100ecf59f45f05d2023606e8e3676b07a316d1c1c364072", + "sha256:732cf1c5cf1324f7bf3b6086976fe62a2ca98f0bf6316f31063c2c67be8797bc", + "sha256:7acdc68e29a446ad17aadaff19c981a36b3bd8c894c3520412c8a7ab1c3e0de7", + "sha256:7acf35cfa7ec9e1e7559c04e7095628f7d06049b5f24dcb58c1a55ef6dc689f8", + "sha256:7c76e751fd1e2f221dec09cdc24040ee486886e943d5d7ffc256e8cf15c75e51", + "sha256:7d3880f213b6f14e9c69ce52beffd1748eecc8669698c4782761887273b6e1bd", + "sha256:802474c18e878b3f9905e160a8b7df87d57885758083eda76c5978265acb41aa", + "sha256:8060fa256862b0c3de64a73ab45bc1ccf381caca464f2647af9075b200828948", + "sha256:8095ef159896e5999a795b0f80e4d64281301a109e442a8d29cd750ca6bd8303", + "sha256:87c2b3fe7e7c96eba376506a76e11514e07e848f737b254e0973e4b5c3a491e9", + "sha256:89b83e76eb00ab0464e7b0752a3ffcb02626e742e9509bc141424a9c3202e8dc", + "sha256:8a45ff7915392a55d9386bb235ea1d1eb9960615f301979f02143fc20036b699", + "sha256:8f1240bde53d3d1676f0aba61b3661560dc9a681cae24d9de33e650864029aa4", + "sha256:9020fd7e58f489fda6a928c31355add0e665fd6b87b21954e675cf9943eafa32", + "sha256:93811d60b0f73d0f049c86f4373a3833b4a38fce374ab151074d929553eb4304", + "sha256:93a6c9230e5a5565847130c0e1005c8d3aa5ca681feb0ed542c4651323d32feb", + "sha256:93cfa6cc25ee2ceb0be81dc61eca9995160b9e16bdb7cca4a00607d57e998918", + "sha256:9646de31f5994e6218311dcf216e971703dbf804c510fd3f84ddb9813c495824", + "sha256:98ebf08c907836b70a8f40e030df8ab6f174dc7f6fa765251d813e89f14069d8", + "sha256:9acf7f0e7106f631cd618eb60ec9bbd6e43045addd5310f66ba1177209567e59", + "sha256:9b2d6e33601c67c074c367fdccdd6033e642284e7a56adc130f18f724c378ca8", + "sha256:9b390f63191bcccbb6044d4c118acdf4fa55f38e5658ac4cfd5a33a6f0c07659", + "sha256:9fc4e35b4afb0af6da55495dd0742ad32ab88150428a6ecdbb3085cbd60714e8", + "sha256:a26fa888025badb5563f283cc19594c215a413e905729e59a5f7cf3f46d66c32", + "sha256:a31806306a60f3565c04c964d6bee0e9d4a5120e1da589e41976b53972edf635", + "sha256:a5f65e89ce50a94d9490d5442a649c6116f53f216c8c14eb37cf9637956482b2", + "sha256:a86b9fef256c2beb162244791fdc025aa55f936d6358e86e2020e512fe2e4972", + "sha256:aa36688c10a08f626fddcf68c2b1b91b0e90b070c26e550a4151a877f5c2d431", + "sha256:aed10d9df1e2fb0011db2713ac64497462e9c2c0208b648c97569da772b959ca", + "sha256:af46a4be0e82df470f68f35316fa16cd1e134d1c5092fc1082e1aad64cce716d", + "sha256:b621a89fc29b3f4b01be6640ec81a6a94b5382bc78fecb876408d57a071e45aa", + "sha256:b6d1c9e1fce5e0a94072667ae2bf0142b89ebbb1917d3531184e060a43f3ee11", + "sha256:b87cddd8107487863fed6994de51e5594a0be267b0b19e213694e99cdd614623", + "sha256:b885695dce7a39b1fd9a609ed9c4cf312e53df2ec028d5a78af7a891b5fbea4d", + "sha256:b9b4da8162cf289781732d6a5ba01d820c42c05943fcdb7de307d03639961db3", + "sha256:bad3b1e0c83849910f28c95953417106f539277035a4b515d1425f93947bc28f", + "sha256:bc117a04bcb461d3bb1b2c5b417aee3442e1e8aa33ebc800481431f4c09fe0c5", + "sha256:bc51f594c2c0863ded6501642dc96701ca8bbea9ced4fa3af0a1aeda8aa634cb", + "sha256:bc63d698c43aea500a84d8b083f830c03808b6cf3933ae4d35a27f0a3d881652", + "sha256:bd33db977ac7af97e8d035ffadb163b00546be22e5f1297b2123f5f9bf0f8a21", + "sha256:c156156798729eadc9ab76ffee96c88b93cc1c3b493f4dd0a4341f53939194ee", + "sha256:c2bc713ee73ab9de4a0d68b0ab0f29612342b63173714742437b977584adb2d8", + "sha256:c339ff4b4739b2a40da463763dd566129762f72926bca611ad9a457a9fe64abd", + "sha256:c5c44e9fa6f4462d0330cb5f5d46fa652512fc86b41d4d1974d0356f263e9105", + "sha256:c5cd20804e3cb0d31e7d899d8dd091f569c33fe40d4bade670a067ab7d31c2ac", + "sha256:c6b232c43e89755ba332c2745ddab059c0bc1a0f01448a3a14d506f8448b1ce6", + "sha256:c7e06baea05de57e1e7548064f505a6964e992674fe61b8f274afe2ac93b6371", + "sha256:c89d2dcb271d24c44f02264233b75d5db8c58831190fa92456a90b87fa17b748", + "sha256:cf3d2299b054e57a9f97ca08704c2843e44f29b57dc69b76a2592ecd212efe1a", + "sha256:cf6844035abf47d52a1c3f4257255af3bf3b0f14d559b08eaa45885418c6c55d", + "sha256:d1a6f889514ee2452300c9a06862fceedef22a2891f1c421a27b1ba52ef130b2", + "sha256:d302deff8cb63a7feffc1844e4dafc8076e566bbf10c5aaaf0f4fe791b8a6bd0", + "sha256:d3cfb4089e96f8f8ee9554da93148a9261aa6612ad2cc202c1a494c7b712e31f", + "sha256:d92144e0cd6e6e841a6ad343e9d58631626eeb4ac96b0322649379b5d4527447", + "sha256:d968116caddd19d63120d1298e62b1bbc694db3360ed0d5df8c3a97edbc12552", + "sha256:d968dde69e3fe903bf9ef00667669dcf04a3e096e33aaf138775106ead138bc8", + "sha256:e38d7a56b1a79ed0bbb9e6fe376d82e3f4dcc646ae47472f2c858e19a597c112", + "sha256:e38d8a325f9a6afac1b1c72d996d1add9e1b99696ce9410538ba5e9aa8fdba02", + "sha256:e665b14ab50aa175cfa306fcb00fffd4e3ff02ceb36ca6a4df00b1246d6a73c4", + "sha256:e812a4e656bbd1c1c15c844b28259c49e26bb384837e44e8d2aa55412c91d2f7", + "sha256:ea4f5ecf9dbea93c827486f59c606684c3496ea71c7ba9a8131932780696e61a", + "sha256:eb5316c9a65c4dde80796aa245b76011bab64eb84461a77b0a61c1bf2970bcc9", + "sha256:f1e8ba6414ac1ae536129e18c069f3eb497df5a74e136e3566471620a4fa5f95", + "sha256:f3982a9c16c1c4bc05a00b65d01ffb8d80ea1a7b6b533be2f1a769d3e989d2c0", + "sha256:f50763cd819d4a52a47b5966d4bb47dee34b637c5fa6402509800eee6ecb61e6", + "sha256:f7c7f89e0bc4246115754e2eda078a111282f6d6ecc6fb458557b724fe6f2aac", + "sha256:f9ea0678806c53d96758e74c6a898f9d506a2e3367a344757f768bef9e069366", + "sha256:fcb91ba42903de637b94a1b64477f381f94ad82c0742c264f9245be76a7a3cbc" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==3.0.0" + "version": "==3.1.0" }, "hpack": { "hashes": [ @@ -1625,11 +1614,11 @@ }, "httpcore": { "hashes": [ - "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", - "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f" + "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", + "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd" ], "markers": "python_version >= '3.8'", - "version": "==1.0.6" + "version": "==1.0.7" }, "httplib2": { "hashes": [ @@ -1685,15 +1674,16 @@ "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", "sha256:fc411e1c0a7dcd2f902c7c48cf079947a7e65b5485dea9decb82b9105ca71a43" ], + "markers": "python_full_version >= '3.8.0'", "version": "==0.6.4" }, "httpx": { "hashes": [ - "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", - "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2" + "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", + "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad" ], "markers": "python_version >= '3.8'", - "version": "==0.27.2" + "version": "==0.28.1" }, "hyperframe": { "hashes": [ @@ -1712,18 +1702,19 @@ }, "icalendar": { "hashes": [ - "sha256:1ff44825d7b41c3f77eac9e09cc67a770dd3c2377430c23b0eb7d91603088892", - "sha256:9bf3d69203bd0366a9a29a8b0e220574580b86d7918afcb628fc6920287922f3" + "sha256:43c2db8632959d634f4e48f6e6131e706bf2cdddad488cf0b72fda079b796bad", + "sha256:46c09b774a6e6948495dafcb166dc15135c8259d0ae25491f154cbc822714b69" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==6.0.1" + "version": "==6.1.0" }, "idna": { "hashes": [ "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" ], + "markers": "python_version >= '3.6'", "version": "==3.10" }, "incremental": { @@ -1752,90 +1743,93 @@ }, "jinja2": { "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", + "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" ], "markers": "python_version >= '3.7'", - "version": "==3.1.4" + "version": "==3.1.5" }, "jiter": { "hashes": [ - "sha256:03a025b52009f47e53ea619175d17e4ded7c035c6fbd44935cb3ada11e1fd592", - "sha256:08be33db6dcc374c9cc19d3633af5e47961a7b10d4c61710bd39e48d52a35824", - "sha256:0b809e39e342c346df454b29bfcc7bca3d957f5d7b60e33dae42b0e5ec13e027", - "sha256:13f9084e3e871a7c0b6e710db54444088b1dd9fbefa54d449b630d5e73bb95d0", - "sha256:15f8395e835cf561c85c1adee72d899abf2733d9df72e9798e6d667c9b5c1f30", - "sha256:18aa9d1626b61c0734b973ed7088f8a3d690d0b7f5384a5270cd04f4d9f26c86", - "sha256:1fad93654d5a7dcce0809aff66e883c98e2618b86656aeb2129db2cd6f26f867", - "sha256:220e0963b4fb507c525c8f58cde3da6b1be0bfddb7ffd6798fb8f2531226cdb1", - "sha256:25f0d2f6e01a8a0fb0eab6d0e469058dab2be46ff3139ed2d1543475b5a1d8e7", - "sha256:26d2bdd5da097e624081c6b5d416d3ee73e5b13f1703bcdadbb1881f0caa1933", - "sha256:31d8e00e1fb4c277df8ab6f31a671f509ebc791a80e5c61fdc6bc8696aaa297c", - "sha256:3343d4706a2b7140e8bd49b6c8b0a82abf9194b3f0f5925a78fc69359f8fc33c", - "sha256:33af2b7d2bf310fdfec2da0177eab2fedab8679d1538d5b86a633ebfbbac4edd", - "sha256:352cd24121e80d3d053fab1cc9806258cad27c53cad99b7a3cac57cf934b12e4", - "sha256:36c0b51a285b68311e207a76c385650322734c8717d16c2eb8af75c9d69506e7", - "sha256:3c843e7c1633470708a3987e8ce617ee2979ee18542d6eb25ae92861af3f1d62", - "sha256:3cbc1a66b4e41511209e97a2866898733c0110b7245791ac604117b7fb3fedb7", - "sha256:3e36a320634f33a07794bb15b8da995dccb94f944d298c8cfe2bd99b1b8a574a", - "sha256:40b03b75f903975f68199fc4ec73d546150919cb7e534f3b51e727c4d6ccca5a", - "sha256:47fee1be677b25d0ef79d687e238dc6ac91a8e553e1a68d0839f38c69e0ee491", - "sha256:4e6e340e8cd92edab7f6a3a904dbbc8137e7f4b347c49a27da9814015cc0420c", - "sha256:51b58f7a0d9e084a43b28b23da2b09fc5e8df6aa2b6a27de43f991293cab85fd", - "sha256:540fcb224d7dc1bcf82f90f2ffb652df96f2851c031adca3c8741cb91877143b", - "sha256:59e2b37f3b9401fc9e619f4d4badcab2e8643a721838bcf695c2318a0475ae42", - "sha256:5a99d4e0b5fc3b05ea732d67eb2092fe894e95a90e6e413f2ea91387e228a307", - "sha256:5f79ce15099154c90ef900d69c6b4c686b64dfe23b0114e0971f2fecd306ec6c", - "sha256:67723a011964971864e0b484b0ecfee6a14de1533cff7ffd71189e92103b38a8", - "sha256:677be9550004f5e010d673d3b2a2b815a8ea07a71484a57d3f85dde7f14cf132", - "sha256:691352e5653af84ed71763c3c427cff05e4d658c508172e01e9c956dfe004aba", - "sha256:77c296d65003cd7ee5d7b0965f6acbe6cffaf9d1fa420ea751f60ef24e85fed5", - "sha256:7a3567c8228afa5ddcce950631c6b17397ed178003dc9ee7e567c4c4dcae9fa0", - "sha256:7cea41c4c673353799906d940eee8f2d8fd1d9561d734aa921ae0f75cb9732f4", - "sha256:7d72fc86474862c9c6d1f87b921b70c362f2b7e8b2e3c798bb7d58e419a6bc0f", - "sha256:81116a6c272a11347b199f0e16b6bd63f4c9d9b52bc108991397dd80d3c78aba", - "sha256:82521000d18c71e41c96960cb36e915a357bc83d63a8bed63154b89d95d05ad1", - "sha256:825651a3f04cf92a661d22cad61fc913400e33aa89b3e3ad9a6aa9dc8a1f5a71", - "sha256:852508a54fe3228432e56019da8b69208ea622a3069458252f725d634e955b31", - "sha256:883d2ced7c21bf06874fdeecab15014c1c6d82216765ca6deef08e335fa719e0", - "sha256:8c97e90fec2da1d5f68ef121444c2c4fa72eabf3240829ad95cf6bbeca42a301", - "sha256:91e63273563401aadc6c52cca64a7921c50b29372441adc104127b910e98a5b6", - "sha256:928bf25eb69ddb292ab8177fe69d3fbf76c7feab5fce1c09265a7dccf25d3991", - "sha256:9df588e9c830b72d8db1dd7d0175af6706b0904f682ea9b1ca8b46028e54d6e9", - "sha256:a2e861658c3fe849efc39b06ebb98d042e4a4c51a8d7d1c3ddc3b1ea091d0784", - "sha256:a311df1fa6be0ccd64c12abcd85458383d96e542531bafbfc0a16ff6feda588f", - "sha256:a31c6fcbe7d6c25d6f1cc6bb1cba576251d32795d09c09961174fe461a1fb5bd", - "sha256:aa25c7a9bf7875a141182b9c95aed487add635da01942ef7ca726e42a0c09058", - "sha256:adef59d5e2394ebbad13b7ed5e0306cceb1df92e2de688824232a91588e77aa7", - "sha256:aeeb0c0325ef96c12a48ea7e23e2e86fe4838e6e0a995f464cf4c79fa791ceeb", - "sha256:b03c24e7da7e75b170c7b2b172d9c5e463aa4b5c95696a368d52c295b3f6847f", - "sha256:b2019d966e98f7c6df24b3b8363998575f47d26471bfb14aade37630fae836a1", - "sha256:b3e02f7a27f2bcc15b7d455c9df05df8ffffcc596a2a541eeda9a3110326e7a3", - "sha256:bae5ae4853cb9644144e9d0755854ce5108d470d31541d83f70ca7ecdc2d1637", - "sha256:bd95375ce3609ec079a97c5d165afdd25693302c071ca60c7ae1cf826eb32022", - "sha256:be7503dd6f4bf02c2a9bacb5cc9335bc59132e7eee9d3e931b13d76fd80d7fda", - "sha256:c74a8d93718137c021d9295248a87c2f9fdc0dcafead12d2930bc459ad40f885", - "sha256:cc56c8f0b2a28ad4d8047f3ae62d25d0e9ae01b99940ec0283263a04724de1f3", - "sha256:d08510593cb57296851080018006dfc394070178d238b767b1879dc1013b106c", - "sha256:d465db62d2d10b489b7e7a33027c4ae3a64374425d757e963f86df5b5f2e7fc5", - "sha256:d71c962f0971347bd552940ab96aa42ceefcd51b88c4ced8a27398182efa8d80", - "sha256:db459ed22d0208940d87f614e1f0ea5a946d29a3cfef71f7e1aab59b6c6b2afb", - "sha256:defee3949313c1f5b55e18be45089970cdb936eb2a0063f5020c4185db1b63c9", - "sha256:e19cd21221fc139fb032e4112986656cb2739e9fe6d84c13956ab30ccc7d4449", - "sha256:e4e85f9e12cd8418ab10e1fcf0e335ae5bb3da26c4d13a0fd9e6a17a674783b6", - "sha256:e51a2d80d5fe0ffb10ed2c82b6004458be4a3f2b9c7d09ed85baa2fbf033f54b", - "sha256:e5c0507131c922defe3f04c527d6838932fcdfd69facebafd7d3574fa3395314", - "sha256:e7b75436d4fa2032b2530ad989e4cb0ca74c655975e3ff49f91a1a3d7f4e1df2", - "sha256:e8bd065be46c2eecc328e419d6557bbc37844c88bb07b7a8d2d6c91c7c4dedc9", - "sha256:e90552109ca8ccd07f47ca99c8a1509ced93920d271bb81780a973279974c5ab", - "sha256:e9ac7c2f092f231f5620bef23ce2e530bd218fc046098747cc390b21b8738a7a", - "sha256:ed69a7971d67b08f152c17c638f0e8c2aa207e9dd3a5fcd3cba294d39b5a8d2d", - "sha256:f1c53615fcfec3b11527c08d19cff6bc870da567ce4e57676c059a3102d3a082", - "sha256:f491cc69ff44e5a1e8bc6bf2b94c1f98d179e1aaf4a554493c171a5b2316b701", - "sha256:f791b6a4da23238c17a81f44f5b55d08a420c5692c1fda84e301a4b036744eb1" + "sha256:025337859077b41548bdcbabe38698bcd93cfe10b06ff66617a48ff92c9aec60", + "sha256:03c9df035d4f8d647f8c210ddc2ae0728387275340668fb30d2421e17d9a0841", + "sha256:08d4c92bf480e19fc3f2717c9ce2aa31dceaa9163839a311424b6862252c943e", + "sha256:0cf5dfa9956d96ff2efb0f8e9c7d055904012c952539a774305aaaf3abdf3d6c", + "sha256:14601dcac4889e0a1c75ccf6a0e4baf70dbc75041e51bcf8d0e9274519df6887", + "sha256:180a8aea058f7535d1c84183c0362c710f4750bef66630c05f40c93c2b152a0f", + "sha256:1c0dfbd1be3cbefc7510102370d86e35d1d53e5a93d48519688b1bf0f761160a", + "sha256:2dd61c5afc88a4fda7d8b2cf03ae5947c6ac7516d32b7a15bf4b49569a5c076b", + "sha256:317b25e98a35ffec5c67efe56a4e9970852632c810d35b34ecdd70cc0e47b3b6", + "sha256:32475a42b2ea7b344069dc1e81445cfc00b9d0e3ca837f0523072432332e9f74", + "sha256:37b2998606d6dadbb5ccda959a33d6a5e853252d921fec1792fc902351bb4e2c", + "sha256:3ac9f578c46f22405ff7f8b1f5848fb753cc4b8377fbec8470a7dc3997ca7566", + "sha256:3b94a33a241bee9e34b8481cdcaa3d5c2116f575e0226e421bed3f7a6ea71cff", + "sha256:4a9220497ca0cb1fe94e3f334f65b9b5102a0b8147646118f020d8ce1de70105", + "sha256:4ab9a87f3784eb0e098f84a32670cfe4a79cb6512fd8f42ae3d0709f06405d18", + "sha256:5127dc1abd809431172bc3fbe8168d6b90556a30bb10acd5ded41c3cfd6f43b6", + "sha256:5672a86d55416ccd214c778efccf3266b84f87b89063b582167d803246354be4", + "sha256:580ccf358539153db147e40751a0b41688a5ceb275e6f3e93d91c9467f42b2e3", + "sha256:58dc9bc9767a1101f4e5e22db1b652161a225874d66f0e5cb8e2c7d1c438b587", + "sha256:5a90a923338531b7970abb063cfc087eebae6ef8ec8139762007188f6bc69a9f", + "sha256:653cf462db4e8c41995e33d865965e79641ef45369d8a11f54cd30888b7e6ff1", + "sha256:66227a2c7b575720c1871c8800d3a0122bb8ee94edb43a5685aa9aceb2782d44", + "sha256:6e5337bf454abddd91bd048ce0dca5134056fc99ca0205258766db35d0a2ea43", + "sha256:70bf4c43652cc294040dbb62256c83c8718370c8b93dd93d934b9a7bf6c4f53c", + "sha256:711e408732d4e9a0208008e5892c2966b485c783cd2d9a681f3eb147cf36c7ef", + "sha256:76e324da7b5da060287c54f2fabd3db5f76468006c811831f051942bf68c9d44", + "sha256:789361ed945d8d42850f919342a8665d2dc79e7e44ca1c97cc786966a21f627a", + "sha256:79aec8172b9e3c6d05fd4b219d5de1ac616bd8da934107325a6c0d0e866a21b6", + "sha256:7efe4853ecd3d6110301665a5178b9856be7e2a9485f49d91aa4d737ad2ae49e", + "sha256:7f22b16b35d5c1df9dfd58843ab2cd25e6bf15191f5a236bed177afade507bfc", + "sha256:83c0efd80b29695058d0fd2fa8a556490dbce9804eac3e281f373bbc99045f6c", + "sha256:859e8eb3507894093d01929e12e267f83b1d5f6221099d3ec976f0c995cb6bd9", + "sha256:8b9931fd36ee513c26b5bf08c940b0ac875de175341cbdd4fa3be109f0492586", + "sha256:8bd2a824d08d8977bb2794ea2682f898ad3d8837932e3a74937e93d62ecbb637", + "sha256:8f2d5ed877f089862f4c7aacf3a542627c1496f972a34d0474ce85ee7d939c27", + "sha256:8ffc86ae5e3e6a93765d49d1ab47b6075a9c978a2b3b80f0f32628f39caa0c88", + "sha256:92249669925bc1c54fcd2ec73f70f2c1d6a817928480ee1c65af5f6b81cdf12d", + "sha256:99d9a1eded738299ba8e106c6779ce5c3893cffa0e32e4485d680588adae6db8", + "sha256:9c63eaef32b7bebac8ebebf4dabebdbc6769a09c127294db6babee38e9f405b9", + "sha256:9e1fa156ee9454642adb7e7234a383884452532bc9d53d5af2d18d98ada1d79c", + "sha256:a2ecaa3c23e7a7cf86d00eda3390c232f4d533cd9ddea4b04f5d0644faf642c5", + "sha256:a6c710d657c8d1d2adbbb5c0b0c6bfcec28fd35bd6b5f016395f9ac43e878a15", + "sha256:a9584de0cd306072635fe4b89742bf26feae858a0683b399ad0c2509011b9dc0", + "sha256:ab7f43235d71e03b941c1630f4b6e3055d46b6cb8728a17663eaac9d8e83a865", + "sha256:af102d3372e917cffce49b521e4c32c497515119dc7bd8a75665e90a718bbf08", + "sha256:b25bd626bde7fb51534190c7e3cb97cee89ee76b76d7585580e22f34f5e3f393", + "sha256:b2dd880785088ff2ad21ffee205e58a8c1ddabc63612444ae41e5e4b321b39c0", + "sha256:b426f72cd77da3fec300ed3bc990895e2dd6b49e3bfe6c438592a3ba660e41ca", + "sha256:ba5bdf56969cad2019d4e8ffd3f879b5fdc792624129741d3d83fc832fef8c7d", + "sha256:bf55846c7b7a680eebaf9c3c48d630e1bf51bdf76c68a5f654b8524335b0ad29", + "sha256:ca1f08b8e43dc3bd0594c992fb1fd2f7ce87f7bf0d44358198d6da8034afdf84", + "sha256:ca29b6371ebc40e496995c94b988a101b9fbbed48a51190a4461fcb0a68b4a36", + "sha256:ca8577f6a413abe29b079bc30f907894d7eb07a865c4df69475e868d73e71c7b", + "sha256:cadcc978f82397d515bb2683fc0d50103acff2a180552654bb92d6045dec2c49", + "sha256:cd646c827b4f85ef4a78e4e58f4f5854fae0caf3db91b59f0d73731448a970c6", + "sha256:cd73d3e740666d0e639f678adb176fad25c1bcbdae88d8d7b857e1783bb4212d", + "sha256:cde031d8413842a1e7501e9129b8e676e62a657f8ec8166e18a70d94d4682855", + "sha256:ce0820f4a3a59ddced7fce696d86a096d5cc48d32a4183483a17671a61edfddc", + "sha256:d20be8b7f606df096e08b0b1b4a3c6f0515e8dac296881fe7461dfa0fb5ec817", + "sha256:d21974d246ed0181558087cd9f76e84e8321091ebfb3a93d4c341479a736f099", + "sha256:d33f94615fcaf872f7fd8cd98ac3b429e435c77619777e8a449d9d27e01134d1", + "sha256:d35c864c2dff13dfd79fb070fc4fc6235d7b9b359efe340e1261deb21b9fcb66", + "sha256:d5c826a221851a8dc028eb6d7d6429ba03184fa3c7e83ae01cd6d3bd1d4bd17d", + "sha256:e41e75344acef3fc59ba4765df29f107f309ca9e8eace5baacabd9217e52a5ee", + "sha256:e52bf98c7e727dd44f7c4acb980cb988448faeafed8433c867888268899b298b", + "sha256:e6ec2be506e7d6f9527dae9ff4b7f54e68ea44a0ef6b098256ddf895218a2f8f", + "sha256:e725edd0929fa79f8349ab4ec7f81c714df51dc4e991539a578e5018fa4a7152", + "sha256:eaa58399c01db555346647a907b4ef6d4f584b123943be6ed5588c3f2359c9f4", + "sha256:eb21aaa9a200d0a80dacc7a81038d2e476ffe473ffdd9c91eb745d623561de05", + "sha256:ecff0dc14f409599bbcafa7e470c00b80f17abc14d1405d38ab02e4b42e55b57", + "sha256:f557c55bc2b7676e74d39d19bcb8775ca295c7a028246175d6a8b431e70835e5", + "sha256:f7200b8f7619d36aa51c803fd52020a2dfbea36ffec1b5e22cab11fd34d95a6d", + "sha256:f9d471356dc16f84ed48768b8ee79f29514295c7295cb41e1133ec0b2b8d637d", + "sha256:fc5adda618205bd4678b146612ce44c3cbfdee9697951f2c0ffdef1f26d72b63", + "sha256:fc9043259ee430ecd71d178fccabd8c332a3bf1e81e50cae43cc2b28d19e4cb7", + "sha256:ffd9fee7d0775ebaba131f7ca2e2d83839a62ad65e8e02fe2bd8fc975cedeb9e" ], "markers": "python_version >= '3.8'", - "version": "==0.6.1" + "version": "==0.8.2" }, "jsonschema": { "hashes": [ @@ -1888,35 +1882,35 @@ }, "langcodes": { "hashes": [ - "sha256:68f686fc3d358f222674ecf697ddcee3ace3c2fe325083ecad2543fd28a20e77", - "sha256:a24879fed238013ac3af2424b9d1124e38b4a38b2044fd297c8ff38e5912e718" + "sha256:1eef8168d07e51e131a2497ffecad4b663f6208e7c3ae3b8dc15c51734a6f801", + "sha256:853c69d1a35e0e13da2f427bb68fb2fa4a8f4fb899e0c62ad8df8d073dcfed33" ], - "markers": "python_version >= '3.8'", - "version": "==3.4.1" + "markers": "python_version >= '3.9'", + "version": "==3.5.0" }, "language-data": { "hashes": [ - "sha256:77d5cab917f91ee0b2f1aa7018443e911cf8985ef734ca2ba3940770f6a3816b", - "sha256:82a86050bbd677bfde87d97885b17566cfe75dad3ac4f5ce44b52c28f752e773" + "sha256:7600ef8aa39555145d06c89f0c324bf7dab834ea0b0a439d8243762e3ebad7ec", + "sha256:e2ee943551b5ae5f89cd0e801d1fc3835bb0ef5b7e9c3a4e8e17b2b214548fbf" ], - "version": "==1.2.0" + "version": "==1.3.0" }, "launchdarkly-eventsource": { "hashes": [ - "sha256:8cb3301ec0daeb5e17eaa37b3b65f6660fab851b317e69271185ef2fb42c2fde", - "sha256:9b5ec7149e2ad9995be22ad5361deb480c229701e6b0cc799e94aa14f067b77b" + "sha256:0fa935b7692555455ac8b44b845cdc16738bd9b2e9ce89ee19b3f8b4adafe3f1", + "sha256:99c29fa9a570aa8d49c9804bcc401028cab8a8954ccbf4a68c3116933301ec33" ], "markers": "python_version >= '3.8'", - "version": "==1.2.0" + "version": "==1.2.1" }, "launchdarkly-server-sdk": { "hashes": [ - "sha256:8cb72f3cd283bd3b1954d59b8197f1467b35d5c10449904aaf560d59d4ceb368", - "sha256:e50a5eef770a5d0c609cf823c60ad9526f2f645e67efc638af31e7582ff62050" + "sha256:4a90e7f62622e7d6107fb4ca7ae7fbc32c3bf028f19822ed5431903210455836", + "sha256:ed3cc007275a669a2036ba79a4b46bff26cbaa05aa4b98cff9f71bd89967ea33" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==9.8.0" + "version": "==9.8.1" }, "linked-services": { "extras": [ @@ -1925,11 +1919,11 @@ "requests" ], "hashes": [ - "sha256:175e677ffc069148ac3674d60482327a3c1ab0f00f049a6002970b64b861e9cc", - "sha256:9e92fb86d0efc11c2d19948ca961f74cf6576b0e1d942e381d219361ca83801a" + "sha256:20217bb021c25adf755bc4638526113745773d2d9b393a1716669a01b980f8d8", + "sha256:cc901826cc11aadeef3b90735f453636f3b5bd78bf7953ae7fe960126619dc41" ], "markers": "python_version >= '3.10'", - "version": "==1.2.3" + "version": "==1.3.1" }, "lxml": { "hashes": [ @@ -2267,11 +2261,11 @@ }, "mistune": { "hashes": [ - "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", - "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8" + "sha256:b05198cf6d671b3deba6c87ec6cf0d4eb7b72c524636eddb6dbf13823b52cee1", + "sha256:dbcac2f78292b9dc066cd03b7a3a26b62d85f8159f2ea5fd28e55df79908d667" ], - "markers": "python_version >= '3.7'", - "version": "==3.0.2" + "markers": "python_version >= '3.8'", + "version": "==3.1.0" }, "mixer": { "hashes": [ @@ -2460,42 +2454,48 @@ }, "mypy": { "hashes": [ - "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc", - "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", - "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", - "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74", - "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a", - "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", - "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", - "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", - "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", - "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", - "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d", - "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6", - "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", - "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", - "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", - "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", - "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", - "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc", - "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", - "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb", - "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", - "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732", - "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", - "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", - "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", - "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", - "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", - "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24", - "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", - "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b", - "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", - "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8" + "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c", + "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", + "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", + "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", + "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9", + "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", + "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", + "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35", + "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319", + "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc", + "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb", + "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", + "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", + "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60", + "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31", + "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", + "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", + "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", + "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", + "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", + "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837", + "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6", + "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", + "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", + "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", + "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", + "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", + "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", + "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b", + "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac", + "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", + "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", + "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", + "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", + "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", + "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", + "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", + "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.13.0" + "version": "==1.14.1" }, "mypy-extensions": { "hashes": [ @@ -2507,11 +2507,11 @@ }, "nbclient": { "hashes": [ - "sha256:4b3f1b7dba531e498449c4db4f53da339c91d449dc11e9af3a43b4eb5c5abb09", - "sha256:f13e3529332a1f1f81d82a53210322476a168bb7090a0289c795fe9cc11c9d3f" + "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", + "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193" ], - "markers": "python_full_version >= '3.8.0'", - "version": "==0.10.0" + "markers": "python_full_version >= '3.9.0'", + "version": "==0.10.2" }, "nbconvert": { "hashes": [ @@ -2532,39 +2532,39 @@ }, "newrelic": { "hashes": [ - "sha256:00df1aa613294cb592a52157f789e75166dbf439cfa9e6cf59f6cf4a265dada9", - "sha256:03ab987eae0452aeb5aed8571c100d1735613a3a227387f99fe54ed38f1ae0e9", - "sha256:23400846dad2283693eade90b6d3c3462301a4b7735c7f76009b1fa445660aeb", - "sha256:32bd34e4cd73c2435472c0b67869fd2db914d6c99d3e1e404e09affe61a8551e", - "sha256:3415b1c7cab5e586e72cca467dd80cd0507f23a3139c02911cf75892fdbb48a6", - "sha256:3521d646c0032db53b7320fe6b6859eebd863f1b47d7c7dd480073727091e50e", - "sha256:36a2218c9e79897d9b5671cdeac30c467d7fbac10cda4f2d79062f2bd0fcaed8", - "sha256:3bee0b9ce1eccf6ac63e51113781743853b1b84c98ae48ed17d0410c352ccb4d", - "sha256:3cd5aeade6462519328fc42f4e98948a45571f3d22360a0559e19a6525c723a6", - "sha256:3d9c8297ba158ce4570fc48cfea7bdf3678b2054baaf0cad4debcbca33c2af3a", - "sha256:3f15a940b6794b4008ab983e7ac3b4d179efe609e040ee96ed5744723fc580c8", - "sha256:501cc575b3fd702a21542a0f5dac59b83f47e2806f5b7c0f4e4510b5474ed77f", - "sha256:60d01303807228718c4099d8550f72d21ee8b61a33555d8974800f6868f2144a", - "sha256:62d521a5d7269c8a5c5838c4ca3b757ef63a13257302c901223c75510cc6f9f5", - "sha256:69aa68cae47c595bdeb95f275d78693ec27a9fd9353bf81257e21f8607134db6", - "sha256:7b449546ebb89feaadfd36fda7735ce06023fc90979b838e244f98369aba5ccb", - "sha256:7f021eac4c2e3b14eab90c608d8bd25b4e3c6b0b0d40796ec1c1260cc47b5e83", - "sha256:a15df23effd09bb1d1f5c38866b75cc5f380b6aa953efbca9e95e79b72744db4", - "sha256:a6d4094d19db924c51ca35da603344907bcbca030822f7a78d5d9c6ad361d419", - "sha256:a6ff022c7556b61b067e8e6b729fe60f437a8356f319ae3b8342858792f3930d", - "sha256:b4220b97669d214e75d2039fea9e0505fde5bc450832210abbc76b9a635785ed", - "sha256:bc693e0db87ab4cf6623847c3949debbcc991554edfb4dd8c02c136e0770b367", - "sha256:c57e79d37ed87e2790c5e66253f9a5d91ed8cc218f160d5a4d062fc759791a78", - "sha256:c6aa9cf936b16d13b65c1b7aa6c722a76a0702469f91bcfc3c5b39f3293181eb", - "sha256:e5809b4111ef3b1d0b5fa66ad06a81de512842370707863d44888c9439f16c4c", - "sha256:e6f822e6a43151af13a748fb2de6ff298aeb6eee03bf6512afba6aaa79211172", - "sha256:ef5d27001d3b5ca53f19d150c60b570c1b0c774d082ab9bf8349f4430ed85b48", - "sha256:f6333aa7051544ddc7f8a85f344bc3f401ddd8635540878da34de7bfd91f5d95", - "sha256:fc3d34db12133b481636384663f45b9ccd7f0f41554a59c15ec37aeb4f77227d" + "sha256:0e5c32c767b64369a8b816629688e62efc58f5ff81b5f4d97f7cf8f3f23d4deb", + "sha256:12572fc2f487dbdb6d2ebec6b1edbe3c3955af7638acf0bda6eff93072d45230", + "sha256:12700b8560a29935ca3cb9868c6f977512d1d4d9f04a91ee16893c52273f0cc1", + "sha256:15a1b1331ff3950824a61dc356cc57acff2051e2f0ca00e30705ba5b10e8b9c9", + "sha256:22b7da78dc374cc5a72bceaf6c03bc26fda6fd398b242a8aa1221e75cfa540b0", + "sha256:32fd7851d2c1c34632c4d6ae6bfe700703c99f1150ded0b16844257925d47861", + "sha256:40a3359672e99c64226b33599daa0d210128a1c7540e26e86400e5710741bf17", + "sha256:4115eb9e5c97ad14e8cbae23dd5275dc162beb2b140c58ac4ba786c020f51aff", + "sha256:4ecf94d7c9103c304d6e27afdf701fd62fcd4320d9ab8d94bcaf4c77cf4576a9", + "sha256:526ebed52279b7202f65b319574c0759620ab102331944211cadc71d5f205a8e", + "sha256:64da7c1155066d115e63523edfd4b9f39361b4c19a46fdde4b710b00342fb31d", + "sha256:6517683ba5c1170de100b0d9314dc3f542b5108acc535700018ba2fef26d3123", + "sha256:68b2f4fe10fed13cae551c41c90cb1686beee4daea0eb03559f552a58557a272", + "sha256:844a38c3ddeb3d2e2d6e568ab8a7f38e12ceaefd77261c66d2c4c9a20c2596ae", + "sha256:8da411cbb14f675c99276e76c92557887f9f5e8044ab2e1e85d4f9826b4eca6b", + "sha256:9df1bf1b1c0b294fce69bf0bbf87c03da544028f69ef6f1b597bf289a6b048e9", + "sha256:9e50b0abfbfd2b6e84896341b6c6b60a1564a98fef64cc0c27b407dac95314e7", + "sha256:a4fdbdd3e6226b01baab71cc2d2406f9f83cd88ee12d72e48593a8f510e240ff", + "sha256:a6658cfe3924c646c1b78a70f60eb890842d8fc31f752e32a450022d397672b8", + "sha256:a8336e0c569ad28ad33427c99bf4a5cb31ec5df8d95ac66c6065023f0b108a3a", + "sha256:b0297bfbef60ee57ce16e40192b3d317a8fb581f40a614a56672173db517117d", + "sha256:b94ca109cfa54ab2c8270d9814923ee3c0abb9e9afd7da026e0b4869f8d93969", + "sha256:c3d2ea64631663155e10f20a793076f271bf072e3564ecf6bd723f94358cb41c", + "sha256:c626fcde15412a905f2699f75d00d9c3af67e2b8f75f3ea1afdd6c0bb9a87d43", + "sha256:c8015ad51d9463c5c7c9977b99214013c276bf8bba3e3f97d5432308d93e37dd", + "sha256:cd36b7a4de9f7c49fde9849abc6fea293f70b09acad9a8573a514da5249b0f66", + "sha256:d69864f83039ffa17e6dab1d986d6a74be2401895b1ea9cb30453788b9372113", + "sha256:de25b50eba6e4b6cc9d0ccd980405ff2cceb4df52738a765dc55586a81c69d3a", + "sha256:e2a1b7b8b5414061bff996d2cef140ab26e9aa8d5e4e2cdce3ce8118adbf2c3e" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==10.2.0" + "version": "==10.4.0" }, "nodeenv": { "hashes": [ @@ -2576,63 +2576,65 @@ }, "numpy": { "hashes": [ - "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", - "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466", - "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", - "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", - "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", - "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", - "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", - "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7", - "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", - "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", - "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", - "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", - "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", - "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", - "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee", - "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", - "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", - "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", - "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", - "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", - "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", - "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86", - "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", - "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", - "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d", - "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2", - "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", - "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", - "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", - "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb", - "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e", - "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", - "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", - "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", - "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", - "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", - "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", - "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952", - "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03", - "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", - "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7", - "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", - "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", - "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5", - "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", - "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", - "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884", - "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", - "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", - "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", - "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", - "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", - "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648" + "sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2", + "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5", + "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60", + "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71", + "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631", + "sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8", + "sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2", + "sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16", + "sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa", + "sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591", + "sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964", + "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821", + "sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484", + "sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957", + "sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800", + "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918", + "sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95", + "sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0", + "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e", + "sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d", + "sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73", + "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59", + "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51", + "sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355", + "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348", + "sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e", + "sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440", + "sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675", + "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84", + "sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046", + "sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab", + "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712", + "sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308", + "sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315", + "sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3", + "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008", + "sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5", + "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2", + "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e", + "sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7", + "sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf", + "sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab", + "sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd", + "sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf", + "sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8", + "sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb", + "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268", + "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d", + "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780", + "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716", + "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e", + "sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528", + "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af", + "sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7", + "sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51" ], "index": "pypi", "markers": "python_version >= '3.10'", - "version": "==2.1.2" + "version": "==2.2.1" }, "oauthlib": { "hashes": [ @@ -2644,20 +2646,20 @@ }, "openai": { "hashes": [ - "sha256:20f408c32fc5cb66e60c6882c994cdca580a5648e10045cd840734194f033418", - "sha256:be2c4e77721b166cce8130e544178b7d579f751b4b074ffbaade3854b6f85ec5" + "sha256:e2910b1170a6b7f88ef491ac3a42c387f08bd3db533411f7ee391d166571d63c", + "sha256:f5a035fd01e141fc743f4b0e02c41ca49be8fab0866d3b67f5f29b4f4d3c0973" ], "index": "pypi", - "markers": "python_full_version >= '3.7.1'", - "version": "==1.53.0" + "markers": "python_version >= '3.8'", + "version": "==1.58.1" }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" }, "pandas": { "hashes": [ @@ -2718,10 +2720,10 @@ }, "phonenumberslite": { "hashes": [ - "sha256:9548bc4c3a7c4d67f7945ba0286e9a37c3ee4ea5531f7ea2518d1cbdc857f50f", - "sha256:db060fd07421306f8fbc4332ca16b8785df0fa70371d3ed632519546c1a11274" + "sha256:c116136c7a2fa7b55b6cea492296f14683077a4817d7a6431c0d83abbd0acfeb", + "sha256:ff121cef3b91ea5ffc952ad573229346694e64039441f41690222fbf6a765886" ], - "version": "==8.13.48" + "version": "==8.13.51" }, "pillow": { "hashes": [ @@ -2861,107 +2863,91 @@ }, "propcache": { "hashes": [ - "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", - "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", - "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", - "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb", - "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", - "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", - "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957", - "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68", - "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f", - "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798", - "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418", - "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6", - "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162", - "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", - "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", - "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", - "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", - "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", - "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", - "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8", - "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638", - "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", - "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", - "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", - "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", - "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", - "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", - "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", - "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", - "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89", - "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", - "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", - "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", - "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861", - "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", - "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", - "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", - "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", - "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", - "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", - "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", - "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563", - "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5", - "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", - "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9", - "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12", - "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", - "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", - "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", - "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9", - "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed", - "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", - "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90", - "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063", - "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", - "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6", - "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8", - "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", - "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", - "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", - "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", - "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", - "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df", - "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", - "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", - "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", - "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", - "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", - "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", - "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", - "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", - "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", - "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6", - "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562", - "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", - "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", - "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", - "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", - "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", - "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", - "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", - "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d", - "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04", - "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", - "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", - "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", - "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea", - "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", - "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1", - "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", - "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", - "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7", - "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", - "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d", - "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", - "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d", - "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", - "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504" + "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4", + "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", + "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", + "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", + "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", + "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", + "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", + "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", + "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf", + "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034", + "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", + "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", + "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", + "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba", + "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", + "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d", + "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae", + "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", + "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2", + "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", + "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", + "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", + "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", + "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", + "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", + "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b", + "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", + "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", + "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587", + "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097", + "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea", + "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", + "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", + "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541", + "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6", + "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634", + "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", + "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d", + "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", + "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", + "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2", + "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf", + "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1", + "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04", + "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", + "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583", + "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb", + "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b", + "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c", + "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958", + "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", + "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4", + "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", + "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e", + "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", + "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", + "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", + "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", + "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", + "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", + "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", + "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", + "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", + "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681", + "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347", + "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", + "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", + "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", + "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", + "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", + "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", + "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3", + "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", + "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", + "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", + "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", + "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", + "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16", + "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", + "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", + "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd", + "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212" ], - "markers": "python_version >= '3.8'", - "version": "==0.2.0" + "markers": "python_version >= '3.9'", + "version": "==0.2.1" }, "proto-plus": { "hashes": [ @@ -2973,20 +2959,20 @@ }, "protobuf": { "hashes": [ - "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24", - "sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535", - "sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b", - "sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548", - "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584", - "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b", - "sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36", - "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", - "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868", - "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687", - "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed" + "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a", + "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355", + "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9", + "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e", + "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9", + "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb", + "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e", + "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e", + "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851", + "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19", + "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181" ], "markers": "python_version >= '3.8'", - "version": "==5.28.3" + "version": "==5.29.2" }, "psycopg": { "extras": [ @@ -3071,10 +3057,10 @@ }, "psycopg-pool": { "hashes": [ - "sha256:53bd8e640625e01b2927b2ad96df8ed8e8f91caea4597d45e7673fc7bbb85eb1", - "sha256:bb942f123bef4b7fbe4d55421bd3fb01829903c95c0f33fd42b7e94e5ac9b52a" + "sha256:61774b5bbf23e8d22bedc7504707135aaf744679f8ef9b3fe29942920746a6ed", + "sha256:f6a22cff0f21f06d72fb2f5cb48c618946777c49385358e0c88d062c59cbd224" ], - "version": "==3.2.3" + "version": "==3.2.4" }, "psycopg2": { "hashes": [ @@ -3093,50 +3079,50 @@ }, "pyarrow": { "hashes": [ - "sha256:00178509f379415a3fcf855af020e3340254f990a8534294ec3cf674d6e255fd", - "sha256:03f40b65a43be159d2f97fd64dc998f769d0995a50c00f07aab58b0b3da87e1f", - "sha256:082ba62bdcb939824ba1ce10b8acef5ab621da1f4c4805e07bfd153617ac19d4", - "sha256:09f30690b99ce34e0da64d20dab372ee54431745e4efb78ac938234a282d15f9", - "sha256:2333f93260674e185cfbf208d2da3007132572e56871f451ba1a556b45dae6e2", - "sha256:28f9c39a56d2c78bf6b87dcc699d520ab850919d4a8c7418cd20eda49874a2ea", - "sha256:2c664ab88b9766413197733c1720d3dcd4190e8fa3bbdc3710384630a0a7207b", - "sha256:2c992716cffb1088414f2b478f7af0175fd0a76fea80841b1706baa8fb0ebaad", - "sha256:2e549a748fa8b8715e734919923f69318c953e077e9c02140ada13e59d043310", - "sha256:320ae9bd45ad7ecc12ec858b3e8e462578de060832b98fc4d671dee9f10d9954", - "sha256:336addb8b6f5208be1b2398442c703a710b6b937b1a046065ee4db65e782ff5a", - "sha256:3ac24b2be732e78a5a3ac0b3aa870d73766dd00beba6e015ea2ea7394f8b4e55", - "sha256:45476490dd4adec5472c92b4d253e245258745d0ccaabe706f8d03288ed60a79", - "sha256:4c381857754da44326f3a49b8b199f7f87a51c2faacd5114352fc78de30d3aba", - "sha256:4d5ca5d707e158540312e09fd907f9f49bacbe779ab5236d9699ced14d2293b8", - "sha256:58a62549a3e0bc9e03df32f350e10e1efb94ec6cf63e3920c3385b26663948ce", - "sha256:5f0510608ccd6e7f02ca8596962afb8c6cc84c453e7be0da4d85f5f4f7b0328a", - "sha256:603cd8ad4976568954598ef0a6d4ed3dfb78aff3d57fa8d6271f470f0ce7d34f", - "sha256:606e9a3dcb0f52307c5040698ea962685fb1c852d72379ee9412be7de9c5f9e2", - "sha256:616ea2826c03c16e87f517c46296621a7c51e30400f6d0a61be645f203aa2b93", - "sha256:66dcc216ebae2eb4c37b223feaf82f15b69d502821dde2da138ec5a3716e7463", - "sha256:6dd1b52d0d58dd8f685ced9971eb49f697d753aa7912f0a8f50833c7a7426319", - "sha256:871b292d4b696b09120ed5bde894f79ee2a5f109cb84470546471df264cae136", - "sha256:8c70c1965cde991b711a98448ccda3486f2a336457cf4ec4dca257a926e149c9", - "sha256:8f40ec677e942374e3d7f2fad6a67a4c2811a8b975e8703c6fd26d3b168a90e2", - "sha256:907ee0aa8ca576f5e0cdc20b5aeb2ad4d3953a3b4769fc4b499e00ef0266f02f", - "sha256:a1824f5b029ddd289919f354bc285992cb4e32da518758c136271cf66046ef22", - "sha256:a6aa027b1a9d2970cf328ccd6dbe4a996bc13c39fd427f502782f5bdb9ca20f5", - "sha256:a71ab0589a63a3e987beb2bc172e05f000a5c5be2636b4b263c44034e215b5d7", - "sha256:b30a927c6dff89ee702686596f27c25160dd6c99be5bcc1513a763ae5b1bfc03", - "sha256:b46591222c864e7da7faa3b19455196416cd8355ff6c2cc2e65726a760a3c420", - "sha256:b5bd7fd32e3ace012d43925ea4fc8bd1b02cc6cc1e9813b518302950e89b5a22", - "sha256:bc1daf7c425f58527900876354390ee41b0ae962a73ad0959b9d829def583bb1", - "sha256:bc97316840a349485fbb137eb8d0f4d7057e1b2c1272b1a20eebbbe1848f5122", - "sha256:be08af84808dff63a76860847c48ec0416928a7b3a17c2f49a072cac7c45efbd", - "sha256:d5795e37c0a33baa618c5e054cd61f586cf76850a251e2b21355e4085def6280", - "sha256:d6331f280c6e4521c69b201a42dd978f60f7e129511a55da9e0bfe426b4ebb8d", - "sha256:dc892be34dbd058e8d189b47db1e33a227d965ea8805a235c8a7286f7fd17d3a", - "sha256:e7ab04f272f98ebffd2a0661e4e126036f6936391ba2889ed2d44c5006237802", - "sha256:eb7e3abcda7e1e6b83c2dc2909c8d045881017270a119cc6ee7fdcfe71d02df8", - "sha256:f1a198a50c409ab2d009fbf20956ace84567d67f2c5701511d4dd561fae6f32e", - "sha256:fe92efcdbfa0bcf2fa602e466d7f2905500f33f09eb90bf0bcf2e6ca41b574c8" - ], - "version": "==18.0.0" + "sha256:01c034b576ce0eef554f7c3d8c341714954be9b3f5d5bc7117006b85fcf302fe", + "sha256:05a5636ec3eb5cc2a36c6edb534a38ef57b2ab127292a716d00eabb887835f1e", + "sha256:0743e503c55be0fdb5c08e7d44853da27f19dc854531c0570f9f394ec9671d54", + "sha256:0ad4892617e1a6c7a551cfc827e072a633eaff758fa09f21c4ee548c30bcaf99", + "sha256:0b331e477e40f07238adc7ba7469c36b908f07c89b95dd4bd3a0ec84a3d1e21e", + "sha256:11b676cd410cf162d3f6a70b43fb9e1e40affbc542a1e9ed3681895f2962d3d9", + "sha256:25dbacab8c5952df0ca6ca0af28f50d45bd31c1ff6fcf79e2d120b4a65ee7181", + "sha256:2c4dd0c9010a25ba03e198fe743b1cc03cd33c08190afff371749c52ccbbaf76", + "sha256:36ac22d7782554754a3b50201b607d553a8d71b78cdf03b33c1125be4b52397c", + "sha256:3b2e2239339c538f3464308fd345113f886ad031ef8266c6f004d49769bb074c", + "sha256:3c35813c11a059056a22a3bef520461310f2f7eea5c8a11ef9de7062a23f8d56", + "sha256:4a4813cb8ecf1809871fd2d64a8eff740a1bd3691bbe55f01a3cf6c5ec869754", + "sha256:4f443122c8e31f4c9199cb23dca29ab9427cef990f283f80fe15b8e124bcc49b", + "sha256:4f97b31b4c4e21ff58c6f330235ff893cc81e23da081b1a4b1c982075e0ed4e9", + "sha256:543ad8459bc438efc46d29a759e1079436290bd583141384c6f7a1068ed6f992", + "sha256:6a276190309aba7bc9d5bd2933230458b3521a4317acfefe69a354f2fe59f2bc", + "sha256:73eeed32e724ea3568bb06161cad5fa7751e45bc2228e33dcb10c614044165c7", + "sha256:74de649d1d2ccb778f7c3afff6085bd5092aed4c23df9feeb45dd6b16f3811aa", + "sha256:84e314d22231357d473eabec709d0ba285fa706a72377f9cc8e1cb3c8013813b", + "sha256:9386d3ca9c145b5539a1cfc75df07757dff870168c959b473a0bccbc3abc8c73", + "sha256:9736ba3c85129d72aefa21b4f3bd715bc4190fe4426715abfff90481e7d00812", + "sha256:9f3a76670b263dc41d0ae877f09124ab96ce10e4e48f3e3e4257273cee61ad0d", + "sha256:a1880dd6772b685e803011a6b43a230c23b566859a6e0c9a276c1e0faf4f4052", + "sha256:acb7564204d3c40babf93a05624fc6a8ec1ab1def295c363afc40b0c9e66c191", + "sha256:ad514dbfcffe30124ce655d72771ae070f30bf850b48bc4d9d3b25993ee0e386", + "sha256:aebc13a11ed3032d8dd6e7171eb6e86d40d67a5639d96c35142bd568b9299324", + "sha256:b516dad76f258a702f7ca0250885fc93d1fa5ac13ad51258e39d402bd9e2e1e4", + "sha256:b76130d835261b38f14fc41fdfb39ad8d672afb84c447126b84d5472244cfaba", + "sha256:ba17845efe3aa358ec266cf9cc2800fa73038211fb27968bfa88acd09261a470", + "sha256:c0a03da7f2758645d17b7b4f83c8bffeae5bbb7f974523fe901f36288d2eab71", + "sha256:c52f81aa6f6575058d8e2c782bf79d4f9fdc89887f16825ec3a66607a5dd8e30", + "sha256:d4b3d2a34780645bed6414e22dda55a92e0fcd1b8a637fba86800ad737057e33", + "sha256:d4f13eee18433f99adefaeb7e01d83b59f73360c231d4782d9ddfaf1c3fbde0a", + "sha256:d6cf5c05f3cee251d80e98726b5c7cc9f21bab9e9783673bac58e6dfab57ecc8", + "sha256:da31fbca07c435be88a0c321402c4e31a2ba61593ec7473630769de8346b54ee", + "sha256:e21488d5cfd3d8b500b3238a6c4b075efabc18f0f6d80b29239737ebd69caa6c", + "sha256:e31e9417ba9c42627574bdbfeada7217ad8a4cbbe45b9d6bdd4b62abbca4c6f6", + "sha256:eaeabf638408de2772ce3d7793b2668d4bb93807deed1725413b70e3156a7854", + "sha256:f266a2c0fc31995a06ebd30bcfdb7f615d7278035ec5b1cd71c48d56daaf30b0", + "sha256:f39a2e0ed32a0970e4e46c262753417a60c43a3246972cfc2d3eb85aedd01b21", + "sha256:f591704ac05dfd0477bb8f8e0bd4b5dc52c1cadf50503858dce3a15db6e46ff2", + "sha256:f96bd502cb11abb08efea6dab09c003305161cb6c9eafd432e35e76e7fa9b90c" + ], + "version": "==18.1.0" }, "pyasn1": { "hashes": [ @@ -3156,60 +3142,80 @@ }, "pycares": { "hashes": [ - "sha256:112a4979c695b1c86f6782163d7dec58d57a3b9510536dcf4826550f9053dd9a", - "sha256:1168a48a834813aa80f412be2df4abaf630528a58d15c704857448b20b1675c0", - "sha256:21a5a0468861ec7df7befa69050f952da13db5427ae41ffe4713bc96291d1d95", - "sha256:229a1675eb33bc9afb1fc463e73ee334950ccc485bc83a43f6ae5839fb4d5fa3", - "sha256:22c00bf659a9fa44d7b405cf1cd69b68b9d37537899898d8cbe5dffa4016b273", - "sha256:23aa3993a352491a47fcf17867f61472f32f874df4adcbb486294bd9fbe8abee", - "sha256:24da119850841d16996713d9c3374ca28a21deee056d609fbbed29065d17e1f6", - "sha256:2eeec144bcf6a7b6f2d74d6e70cbba7886a84dd373c886f06cb137a07de4954c", - "sha256:34736a2ffaa9c08ca9c707011a2d7b69074bbf82d645d8138bba771479b2362f", - "sha256:3aebc73e5ad70464f998f77f2da2063aa617cbd8d3e8174dd7c5b4518f967153", - "sha256:3eaa6681c0a3e3f3868c77aca14b7760fed35fdfda2fe587e15c701950e7bc69", - "sha256:4afc2644423f4eef97857a9fd61be9758ce5e336b4b0bd3d591238bb4b8b03e0", - "sha256:52084961262232ec04bd75f5043aed7e5d8d9695e542ff691dfef0110209f2d4", - "sha256:56cf3349fa3a2e67ed387a7974c11d233734636fe19facfcda261b411af14d80", - "sha256:5ed4e04af4012f875b78219d34434a6d08a67175150ac1b79eb70ab585d4ba8c", - "sha256:64965dc19c578a683ea73487a215a8897276224e004d50eeb21f0bc7a0b63c88", - "sha256:6ef64649eba56448f65e26546d85c860709844d2fc22ef14d324fe0b27f761a9", - "sha256:77cf5a2fd5583c670de41a7f4a7b46e5cbabe7180d8029f728571f4d2e864084", - "sha256:7bddc6adba8f699728f7fc1c9ce8cef359817ad78e2ed52b9502cb5f8dc7f741", - "sha256:813d661cbe2e37d87da2d16b7110a6860e93ddb11735c6919c8a3545c7b9c8d8", - "sha256:82bba2ab77eb5addbf9758d514d9bdef3c1bfe7d1649a47bd9a0d55a23ef478b", - "sha256:8bf2eaa83a5987e48fa63302f0fe7ce3275cfda87b34d40fef9ce703fb3ac002", - "sha256:8d186dafccdaa3409194c0f94db93c1a5d191145a275f19da6591f9499b8e7b8", - "sha256:8f64cb58729689d4d0e78f0bfb4c25ce2f851d0274c0273ac751795c04b8798a", - "sha256:902461a92b6a80fd5041a2ec5235680c7cc35e43615639ec2a40e63fca2dfb51", - "sha256:917f08f0b5d9324e9a34211e68d27447c552b50ab967044776bbab7e42a553a2", - "sha256:94d6962db81541eb0396d2f0dfcbb18cdb8c8b251d165efc2d974ae652c547d4", - "sha256:97892cced5794d721fb4ff8765764aa4ea48fe8b2c3820677505b96b83d4ef47", - "sha256:9a0303428d013ccf5c51de59c83f9127aba6200adb7fd4be57eddb432a1edd2a", - "sha256:9dc04c54c6ea615210c1b9e803d0e2d2255f87a3d5d119b6482c8f0dfa15b26b", - "sha256:a0c5368206057884cde18602580083aeaad9b860e2eac14fd253543158ce1e93", - "sha256:ad58e284a658a8a6a84af2e0b62f2f961f303cedfe551854d7bd40c3cbb61912", - "sha256:afb91792f1556f97be7f7acb57dc7756d89c5a87bd8b90363a77dbf9ea653817", - "sha256:b61579cecf1f4d616e5ea31a6e423a16680ab0d3a24a2ffe7bb1d4ee162477ff", - "sha256:b7af06968cbf6851566e806bf3e72825b0e6671832a2cbe840be1d2d65350710", - "sha256:bce8db2fc6f3174bd39b81405210b9b88d7b607d33e56a970c34a0c190da0490", - "sha256:bfb89ca9e3d0a9b5332deeb666b2ede9d3469107742158f4aeda5ce032d003f4", - "sha256:c680fef1b502ee680f8f0b95a41af4ec2c234e50e16c0af5bbda31999d3584bd", - "sha256:c6a8bde63106f162fca736e842a916853cad3c8d9d137e11c9ffa37efa818b02", - "sha256:cb49d5805cd347c404f928c5ae7c35e86ba0c58ffa701dbe905365e77ce7d641", - "sha256:ceb12974367b0a68a05d52f4162b29f575d241bd53de155efe632bf2c943c7f6", - "sha256:d33e2a1120887e89075f7f814ec144f66a6ce06a54f5722ccefc62fbeda83cff", - "sha256:db24c4e7fea4a052c6e869cbf387dd85d53b9736cfe1ef5d8d568d1ca925e977", - "sha256:e3a6f7cfdfd11eb5493d6d632e582408c8f3b429f295f8799c584c108b28db6f", - "sha256:eb66c30eb11e877976b7ead13632082a8621df648c408b8e15cdb91a452dd502", - "sha256:ed2a38e34bec6f2586435f6ff0bc5fe11d14bebd7ed492cf739a424e81681540", - "sha256:f36bdc1562142e3695555d2f4ac0cb69af165eddcefa98efc1c79495b533481f", - "sha256:f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2", - "sha256:f5f646eec041db6ffdbcaf3e0756fb92018f7af3266138c756bb09d2b5baadec", - "sha256:fd644505a8cfd7f6584d33a9066d4e3d47700f050ef1490230c962de5dfb28c6", - "sha256:fff16b09042ba077f7b8aa5868d1d22456f0002574d0ba43462b10a009331677" + "sha256:011cd670da7caf55664c944abb71ec39af82b837f8d48da7cf0eec80f5682c4c", + "sha256:018e700fb0d1a2db5ec96e404ffa85ed97cc96e96d6af0bb9548111e37cf36a3", + "sha256:025b6c2ffea4e9fb8f9a097381c2fecb24aff23fbd6906e70da22ec9ba60e19d", + "sha256:0a6649d713df73266708642fc3d04f110c0a66bee510fbce4cc5fed79df42083", + "sha256:0d3de65cab653979dcc491e03f596566c9d40346c9deb088e0f9fe70600d8737", + "sha256:0f38e45d23660ed1dafdb956fd263ae4735530ef1578aa2bf2caabb94cee4523", + "sha256:1004b8a17614e33410b4b1bb68360977667f1cc9ab2dbcfb27240d6703e4cb6a", + "sha256:13a82fad8239d6fbcf916099bee17d8b5666d0ddb77dace431e0f7961c9427ab", + "sha256:160e92588cdf1a0fa3a7015f47990b508d50efd9109ea4d719dee31c058f0648", + "sha256:17a060cfc469828abf7f5945964d505bd8c0a756942fee159538f7885169752e", + "sha256:1fd87cb26b317a9988abfcfa4e4dbc55d5f20177e5979ad4d854468a9246c187", + "sha256:27a77b43604b3ba24e4fc49fd3ea59f50f7d89c7255f1f1ea46928b26cccacfa", + "sha256:2c9c1055c622258a0f315560b2880a372363484b87cbef48af092624804caa72", + "sha256:2ce10672c4cfd1c5fb6718e8b25f0336ca11c89aab88aa6df53dafc4e41df740", + "sha256:2d435a3b8468c656a7e7180dd7c4794510f6c612c33ad61a0fff6e440621f8b5", + "sha256:3125df81b657971ee5c0333f8f560ba0151db1eb7cf04aea7d783bb433b306c1", + "sha256:32919f6eda7f5ea4df3e64149fc5792b0d455277d23d6d0fc365142062f35d80", + "sha256:32d33c4ffae31d1b544adebe0b9aee2be1fb18aedd3f4f91e41c495ccbafd6d8", + "sha256:3316d490b4ce1a69f034881ac1ea7608f5f24ea5293db24ab574ac70b7d7e407", + "sha256:361262805bb09742c364ec0117842043c950339e38561009bcabbb6ac89458ef", + "sha256:37add862461f9a3fc7ee4dd8b68465812b39456e21cebd5a33c414131ac05060", + "sha256:429fe2065581a64a5f024f507b5f679bf37ea0ed39c3ba6289dba907e1c8a8f4", + "sha256:4c6922ecbe458c13a4a2c1177bbce38abc44b5f086bc82115a92eab34418915f", + "sha256:506efbe5017807747ccd1bdcb3c2f6e64635bc01fee01a50c0b97d649018c162", + "sha256:525c77ea44546c12f379641aee163585d403cf50e29b04a06059d6aac894e956", + "sha256:5703ec878b5c1efacdbf24ceaedfa606112fc67af5564f4db99c2c210f3ffadc", + "sha256:597c0950ede240c3a779f023fcf2442207fc11e570d3ca4ccdbb0db5bbaf2588", + "sha256:5c8b87c05740595bc8051dc98e51f022f003750e7da90f62f7a9fd50e330b196", + "sha256:5ca7a1dba7b88290710db45012e0903c21c839fa0a2b9ddc100bba8e66bfb251", + "sha256:6028cb8766f0fea1d2caa69fac23621fbe2cff9ce6968374e165737258703a33", + "sha256:6d2afb3c0776467055bf33db843ef483d25639be0f32e3a13ef5d4dc64098bf5", + "sha256:723ba0803b016294430e40e544503fed9164949b694342c2552ab189e2b688ef", + "sha256:78c9890d93108c70708babee8a783e6021233f1f0a763d3634add6fd429aae58", + "sha256:8371f5ee1efb33d6276e275d152c9c5605e5f2e58a9e168519ec1f9e13dd95ae", + "sha256:887ac451ffe6e39ee46d3d0989c7bb829933d77e1dad5776511d825fc7e6a25b", + "sha256:8addbf3408af1010f50fd67ef634a6cb239ccb9c534c32a40713f3b8d306a98e", + "sha256:95522d4840d702fd766439a7c7cd747935aa54cf0b8675e9fadd8414dd9dd0df", + "sha256:96d3aecd747a3fcd1e12c1ea1481b0813b4e0e80d40f314db7a86dda5bb1bd94", + "sha256:9aa0da03c4df6ed0f87dd52a293bd0508734515041cc5be0f85d9edc1814914f", + "sha256:9e9b7d1a8de703283e4735c0e532ba4bc600e88de872dcd1a9a4950cf74d9f4f", + "sha256:9ea2f6d48e64b413b97b41b47392087b452af9bf9f9d4d6d05305a159f45909f", + "sha256:9f87d8da20a3a80ab05fe80c14a62bf078bd726ca6af609edbeb376fb97d50ab", + "sha256:a6f4b9063e3dd70460400367917698f209c10aabb68bf70b09e364895444487d", + "sha256:a90aecd41188884e57ae32507a2c6b010c60b791a253083761bbb37a488ecaed", + "sha256:ac57d7bda925c10b997434e7ce30a2c3689c2e96bab9fd0a1165d5577378eecd", + "sha256:aea1ebf52767c777d10a1b3d03844b9b05cc892714b3ee177d5d9fbff74fb9fa", + "sha256:aed5c2732f3a6bdbbfab202267d37044ca1162f690b9d34b7ece97ba43f27453", + "sha256:b1859ea770a7abec40a6d02b5ab03c2396c4900c01f4e50ddb6c0dca4c2a6a7c", + "sha256:b5c67930497fb2b1dbcaa85f8c4188fc2cb62e41d787deeed2d33cfe9dd6bf52", + "sha256:b604af76b57469ff68b44e9e4c857eaee43bc5035f4f183f07f4f7149191fe1b", + "sha256:ba17d8e5eeec4b2e0eb1a6a840bae9e62cd1c1c9cbc8dc9db9d1b9fdf33d0b54", + "sha256:ba69f8123995aa3df99f6ebc726fc6a4b08e467a957b215c0a82749b901d5eed", + "sha256:bc7a1d8ed7c7a4de17706a3c89b305b02eb64c778897e6727c043e5b9dd0d853", + "sha256:c1d0d5e69fa29e41b590a9dd5842454e8f34e2b928c92540aaf87e0161de8120", + "sha256:c469ec9fbe0526f45a98f67c1ea55be03abf30809c4f9c9be4bc93fb6806304d", + "sha256:c589bd4f9160bfdb2f8080cf564bb120a4312cf091db07fe417f8e58a896a63c", + "sha256:c76a9096fd5dc49c61c5235ea7032e8b43f4382800d64ca1e0e0cda700c082aa", + "sha256:cdc3c0be7b5b83e78e28818fecd0405bd401110dd6e2e66f7f10713c1188362c", + "sha256:ceaf71bcd7b6447705e689b8fee8836c20c6148511a90122981f524a84bfcca9", + "sha256:d0428ef42fcf575e197047e6a47892404faa34231902a453b3dfed66af4178b3", + "sha256:d87758e09dbf52c27ed7cf7bc7eaf8b3226217d10c52b03d61a14d59f40fcae1", + "sha256:de6e55bd9af595b112ac6080ac0a0d52b5853d0d8e6d01ac65ff09e51e62490a", + "sha256:e322e8ce810026f6e0c7c2a254b9ed02191ab8d42fa2ce6808ede1bdccab8e65", + "sha256:e4709ce4fd9dbee24b1397f71a2adb3267323bb5ad5e7fde3f87873d172dd156", + "sha256:e48b20b59cdc929cc712a8b22e89c273256e482b49bb8999af98d2c6fc4563c2", + "sha256:eb20d84269ddffb177b6048e3bc03d0b9ffe17592093d900d5544805958d86b3", + "sha256:ed1d050d2c6d74a77c1b6c51fd99426cc000b4202a50d28d6ca75f7433099a6b", + "sha256:f096699c46f5dde2c7a8d91501a36d2d58500f4d63682e2ec14a0fed7cca6402", + "sha256:f742acc6d29a99ffc14e3f154b3848ea05c5533b71065e0f0a0fd99c527491b2", + "sha256:fd458ee69800195247aa19b5675c5914cbc091c5a220e4f0e96777a31bb555c1", + "sha256:fefc7bebbe39b2e3b4b9615471233a8f7356b96129a7db9030313a3ae4ecc42d" ], - "markers": "python_version >= '3.8'", - "version": "==4.4.0" + "markers": "python_version >= '3.9'", + "version": "==4.5.0" }, "pycparser": { "hashes": [ @@ -3221,106 +3227,117 @@ }, "pydantic": { "hashes": [ - "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", - "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12" + "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d", + "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06" ], "markers": "python_version >= '3.8'", - "version": "==2.9.2" + "version": "==2.10.4" }, "pydantic-core": { "hashes": [ - "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36", - "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", - "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", - "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", - "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c", - "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", - "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29", - "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744", - "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", - "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", - "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", - "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", - "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577", - "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", - "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", - "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", - "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368", - "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", - "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", - "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2", - "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6", - "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", - "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", - "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", - "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", - "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", - "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271", - "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", - "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb", - "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13", - "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323", - "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556", - "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665", - "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef", - "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", - "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", - "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", - "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", - "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", - "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", - "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", - "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", - "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", - "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21", - "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", - "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", - "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658", - "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", - "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3", - "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb", - "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59", - "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", - "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", - "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", - "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", - "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", - "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55", - "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad", - "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a", - "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605", - "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e", - "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", - "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", - "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", - "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", - "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", - "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", - "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", - "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555", - "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", - "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6", - "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", - "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b", - "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df", - "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", - "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", - "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", - "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", - "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040", - "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12", - "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", - "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", - "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", - "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", - "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", - "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", - "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8", - "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", - "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607" + "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278", + "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", + "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", + "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f", + "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", + "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", + "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54", + "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630", + "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", + "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", + "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", + "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", + "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", + "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", + "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", + "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", + "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", + "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd", + "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", + "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", + "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", + "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", + "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", + "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", + "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", + "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", + "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", + "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", + "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", + "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", + "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", + "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf", + "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", + "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", + "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76", + "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362", + "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", + "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", + "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320", + "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118", + "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96", + "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", + "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046", + "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", + "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", + "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", + "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", + "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67", + "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", + "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", + "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", + "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", + "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", + "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b", + "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", + "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", + "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", + "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145", + "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", + "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", + "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", + "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", + "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", + "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", + "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5", + "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", + "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", + "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", + "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", + "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da", + "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", + "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", + "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993", + "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656", + "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4", + "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", + "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb", + "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d", + "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", + "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e", + "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", + "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc", + "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a", + "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9", + "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506", + "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b", + "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1", + "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", + "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", + "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", + "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", + "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", + "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", + "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", + "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308", + "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2", + "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228", + "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b", + "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", + "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad" ], "markers": "python_version >= '3.8'", - "version": "==2.23.4" + "version": "==2.27.2" }, "pyfcm": { "hashes": [ @@ -3332,12 +3349,12 @@ }, "pygithub": { "hashes": [ - "sha256:6601e22627e87bac192f1e2e39c6e6f69a43152cfb8f307cee575879320b3051", - "sha256:81935aa4bdc939fba98fee1cb47422c09157c56a27966476ff92775602b9ee24" + "sha256:b0b635999a658ab8e08720bdd3318893ff20e2275f6446fcf35bf3f44f2c0fd2", + "sha256:e1613ac508a9be710920d26eb18b1905ebd9926aa49398e88151c1b526aad3cf" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2.4.0" + "version": "==2.5.0" }, "pygments": { "hashes": [ @@ -3352,11 +3369,11 @@ "crypto" ], "hashes": [ - "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850", - "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c" + "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", + "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb" ], - "markers": "python_version >= '3.8'", - "version": "==2.9.0" + "markers": "python_version >= '3.9'", + "version": "==2.10.1" }, "pymemcache": { "hashes": [ @@ -3384,42 +3401,43 @@ }, "pyopenssl": { "hashes": [ - "sha256:4247f0dbe3748d560dcbb2ff3ea01af0f9a1a001ef5f7c4c647956ed8cbf0e95", - "sha256:967d5719b12b243588573f39b0c677637145c7a1ffedcd495a487e58177fbb8d" + "sha256:49f7a019577d834746bc55c5fce6ecbcec0f2b4ec5ce1cf43a9a173b8138bb36", + "sha256:e474f5a473cd7f92221cc04976e48f4d11502804657a08a989fb3be5514c904a" ], - "version": "==24.2.1" + "markers": "python_version >= '3.7'", + "version": "==24.3.0" }, "pyparsing": { "hashes": [ "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84", "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c" ], - "markers": "python_version > '3.0'", + "markers": "python_version >= '3.9'", "version": "==3.2.0" }, "pyrfc3339": { "hashes": [ - "sha256:67196cb83b470709c580bb4738b83165e67c6cc60e1f2e4f286cfcb402a926f4", - "sha256:81b8cbe1519cdb79bed04910dd6fa4e181faf8c88dff1e1b987b5f7ab23a5b1a" + "sha256:30b70a366acac3df7386b558c21af871522560ed7f3f73cf344b8c2cbb8b0c9d", + "sha256:e47843379ea35c1296c3b6c67a948a1a490ae0584edfcbdea0eaffb5dd29960b" ], - "version": "==1.1" + "version": "==2.0.1" }, "pyright": { "hashes": [ - "sha256:577de60224f7fe36505d5b181231e3a395d427b7873be0bbcaa962a29ea93a60", - "sha256:6a1f495a261a72e12ad17e20d1ae3df4511223c773b19407cfa006229b1b08a5" + "sha256:54fa186f8b3e8a55a44ebfa842636635688670c6896dcf6cf4a7fc75062f4d15", + "sha256:66b2d42cdf5c3cbab05f2f4b76e8bec8aa78e679bfa0b6ad7b923d9e027cadb2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.1.387" + "version": "==1.1.391" }, "pytest": { "hashes": [ - "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", - "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2" + "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", + "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" ], "markers": "python_version >= '3.8'", - "version": "==8.3.3" + "version": "==8.3.4" }, "pytest-django": { "hashes": [ @@ -3670,11 +3688,11 @@ "hiredis" ], "hashes": [ - "sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0", - "sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897" + "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f", + "sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4" ], "markers": "python_version >= '3.8'", - "version": "==5.2.0" + "version": "==5.2.1" }, "referencing": { "hashes": [ @@ -3703,112 +3721,112 @@ }, "rpds-py": { "hashes": [ - "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c", - "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585", - "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5", - "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6", - "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef", - "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2", - "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29", - "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318", - "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b", - "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399", - "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739", - "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee", - "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174", - "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a", - "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344", - "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2", - "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03", - "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5", - "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22", - "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e", - "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96", - "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91", - "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752", - "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075", - "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253", - "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee", - "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad", - "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5", - "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce", - "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7", - "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b", - "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8", - "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57", - "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3", - "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec", - "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209", - "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921", - "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045", - "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074", - "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580", - "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7", - "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5", - "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3", - "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0", - "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24", - "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139", - "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db", - "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc", - "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789", - "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f", - "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2", - "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c", - "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232", - "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6", - "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c", - "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29", - "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489", - "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94", - "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751", - "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2", - "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda", - "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9", - "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51", - "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c", - "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8", - "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989", - "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511", - "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1", - "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2", - "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150", - "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c", - "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965", - "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f", - "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58", - "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b", - "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f", - "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d", - "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821", - "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de", - "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121", - "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855", - "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272", - "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60", - "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02", - "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1", - "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140", - "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879", - "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940", - "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364", - "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4", - "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e", - "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420", - "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5", - "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24", - "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c", - "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf", - "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f", - "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e", - "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab", - "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08", - "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92", - "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a", - "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8" + "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518", + "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", + "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", + "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5", + "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9", + "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543", + "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2", + "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a", + "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d", + "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", + "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d", + "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd", + "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b", + "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4", + "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99", + "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", + "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd", + "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe", + "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1", + "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", + "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f", + "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3", + "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca", + "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d", + "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e", + "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc", + "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea", + "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", + "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b", + "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c", + "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff", + "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723", + "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e", + "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493", + "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6", + "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83", + "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091", + "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1", + "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", + "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1", + "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728", + "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16", + "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c", + "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", + "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7", + "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a", + "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730", + "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967", + "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25", + "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24", + "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055", + "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d", + "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0", + "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e", + "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", + "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c", + "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f", + "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd", + "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652", + "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8", + "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11", + "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333", + "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96", + "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64", + "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b", + "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e", + "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c", + "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9", + "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec", + "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb", + "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37", + "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad", + "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9", + "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c", + "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf", + "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", + "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f", + "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d", + "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09", + "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", + "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566", + "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74", + "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338", + "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", + "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c", + "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648", + "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84", + "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3", + "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123", + "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520", + "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831", + "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", + "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf", + "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b", + "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2", + "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3", + "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130", + "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b", + "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de", + "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5", + "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d", + "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00", + "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e" ], - "markers": "python_version >= '3.8'", - "version": "==0.20.0" + "markers": "python_version >= '3.9'", + "version": "==0.22.3" }, "rsa": { "hashes": [ @@ -3847,23 +3865,24 @@ "sha256:6b047fbd8a84fd0bb0d55ebce4031e400562b9196e1e0d3e0fe2b8a59f6d4a85", "sha256:b8683ba13f0d39c6cd5d625d2c5f65421d6d707b013b375c355751557cbe8e09" ], + "markers": "python_version >= '3.8'", "version": "==24.2.0" }, "setuptools": { "hashes": [ - "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", - "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686" + "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", + "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d" ], - "markers": "python_version >= '3.8'", - "version": "==75.3.0" + "markers": "python_version >= '3.9'", + "version": "==75.6.0" }, "six": { "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==1.16.0" + "version": "==1.17.0" }, "sniffio": { "hashes": [ @@ -3945,20 +3964,20 @@ }, "sqlparse": { "hashes": [ - "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4", - "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e" + "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", + "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca" ], "markers": "python_version >= '3.8'", - "version": "==0.5.1" + "version": "==0.5.3" }, "stripe": { "hashes": [ - "sha256:4c53d61d7b596070324bfa5d7215843145fe5466e48973d828aab41ad209b5ce", - "sha256:dec812eabc95488862be40e6c799acdaf2e1225d686490a793f949fab745fdd0" + "sha256:7ddd251b622d490fe57d78487855dc9f4d95b1bb113607e81fd377037a133d5a", + "sha256:8aa47a241de0355c383c916c4ef7273ab666f096a44ee7081e357db4a36f0cce" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==11.2.0" + "version": "==11.4.1" }, "text-unidecode": { "hashes": [ @@ -3984,28 +4003,28 @@ }, "tornado": { "hashes": [ - "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8", - "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f", - "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4", - "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3", - "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14", - "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842", - "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9", - "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698", - "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7", - "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d", - "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4" + "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", + "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", + "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", + "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", + "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", + "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", + "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", + "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf", + "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", + "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", + "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1" ], "markers": "python_version >= '3.8'", - "version": "==6.4.1" + "version": "==6.4.2" }, "tqdm": { "hashes": [ - "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63", - "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090" + "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", + "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2" ], "markers": "python_version >= '3.7'", - "version": "==4.66.6" + "version": "==4.67.1" }, "traitlets": { "hashes": [ @@ -4017,12 +4036,12 @@ }, "twilio": { "hashes": [ - "sha256:c5d7f4cfeb50a7928397b8f819c8f7fb2bb956a1a2cabbda1df1d7a40f9ce1d7", - "sha256:d42691f7fe1faaa5ba82942f169bfea4d7f01a0a542a456d82018fb49bd1f5b2" + "sha256:2447e041cec11167d7765aaa62ab1dae3b82b712245ca9a966096acd8b9f426f", + "sha256:e24c640696ccc726bba14160951da3cfc6b4bcb772fdcb3e8c16dc3cc851ef12" ], "index": "pypi", "markers": "python_full_version >= '3.7.0'", - "version": "==9.3.6" + "version": "==9.4.1" }, "twisted": { "extras": [ @@ -4030,11 +4049,11 @@ "tls" ], "hashes": [ - "sha256:02951299672595fea0f70fa2d5f7b5e3d56836157eda68859a6ad6492d36756e", - "sha256:67aa7c8aa94387385302acf44ade12967c747858c8bcce0f11d38077a11c5326" + "sha256:695d0556d5ec579dcc464d2856b634880ed1319f45b10d19043f2b57eb0115b5", + "sha256:fe403076c71f04d5d2d789a755b687c5637ec3bcd3b2b8252d76f2ba65f54261" ], "markers": "python_full_version >= '3.8.0'", - "version": "==24.10.0" + "version": "==24.11.0" }, "txaio": { "hashes": [ @@ -4071,31 +4090,31 @@ }, "urllib3": { "hashes": [ - "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", - "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", + "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.8'", - "version": "==2.2.3" + "markers": "python_version >= '3.9'", + "version": "==2.3.0" }, "uvicorn": { "extras": [ "standard" ], "hashes": [ - "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82", - "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e" + "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", + "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9" ], - "markers": "python_version >= '3.8'", - "version": "==0.32.0" + "markers": "python_version >= '3.9'", + "version": "==0.34.0" }, "uvicorn-worker": { "hashes": [ - "sha256:65dcef25ab80a62e0919640f9582216ee05b3bb1dc2f0e58b354ca0511c398fb", - "sha256:f6894544391796be6eeed37d48cae9d7739e5a105f7e37061eccef2eac5a0295" + "sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b", + "sha256:ef0fe8aad27b0290a9e602a256b03f5a5da3a9e5f942414ca587b645ec77dd52" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==0.2.0" + "markers": "python_version >= '3.9'", + "version": "==0.3.0" }, "uvloop": { "hashes": [ @@ -4137,6 +4156,7 @@ "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2" ], + "markers": "python_full_version >= '3.8.0'", "version": "==0.21.0" }, "vine": { @@ -4149,91 +4169,80 @@ }, "watchfiles": { "hashes": [ - "sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", - "sha256:01def80eb62bd5db99a798d5e1f5f940ca0a05986dcfae21d833af7a46f7ee22", - "sha256:07cdef0c84c03375f4e24642ef8d8178e533596b229d32d2bbd69e5128ede02a", - "sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", - "sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", - "sha256:21ab23fdc1208086d99ad3f69c231ba265628014d4aed31d4e8746bd59e88cd1", - "sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", - "sha256:2e28d91ef48eab0afb939fa446d8ebe77e2f7593f5f463fd2bb2b14132f95b6e", - "sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", - "sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", - "sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", - "sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", - "sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", - "sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", - "sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", - "sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", - "sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", - "sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", - "sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", - "sha256:4933a508d2f78099162da473841c652ad0de892719043d3f07cc83b33dfd9d91", - "sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", - "sha256:49fb58bcaa343fedc6a9e91f90195b20ccb3135447dc9e4e2570c3a39565853e", - "sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", - "sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", - "sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", - "sha256:4d28cea3c976499475f5b7a2fec6b3a36208656963c1a856d328aeae056fc5c1", - "sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", - "sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", - "sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", - "sha256:5c51749f3e4e269231510da426ce4a44beb98db2dce9097225c338f815b05d4f", - "sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", - "sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", - "sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", - "sha256:7138eff8baa883aeaa074359daabb8b6c1e73ffe69d5accdc907d62e50b1c0da", - "sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", - "sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", - "sha256:78470906a6be5199524641f538bd2c56bb809cd4bf29a566a75051610bc982c3", - "sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", - "sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", - "sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", - "sha256:82b2509f08761f29a0fdad35f7e1638b8ab1adfa2666d41b794090361fb8b855", - "sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", - "sha256:85d5f0c7771dcc7a26c7a27145059b6bb0ce06e4e751ed76cdf123d7039b60b5", - "sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", - "sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", - "sha256:951088d12d339690a92cef2ec5d3cfd957692834c72ffd570ea76a6790222777", - "sha256:95cf3b95ea665ab03f5a54765fa41abf0529dbaf372c3b83d91ad2cfa695779b", - "sha256:96619302d4374de5e2345b2b622dc481257a99431277662c30f606f3e22f42be", - "sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", - "sha256:9a60e2bf9dc6afe7f743e7c9b149d1fdd6dbf35153c78fe3a14ae1a9aee3d98b", - "sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", - "sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", - "sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", - "sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", - "sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", - "sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", - "sha256:b3ef2c69c655db63deb96b3c3e587084612f9b1fa983df5e0c3379d41307467f", - "sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", - "sha256:b665caeeda58625c3946ad7308fbd88a086ee51ccb706307e5b1fa91556ac886", - "sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", - "sha256:b995bfa6bf01a9e09b884077a6d37070464b529d8682d7691c2d3b540d357a0c", - "sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", - "sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", - "sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", - "sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", - "sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", - "sha256:d337193bbf3e45171c8025e291530fb7548a93c45253897cd764a6a71c937ed9", - "sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", - "sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", - "sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", - "sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", - "sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444", - "sha256:e5171ef898299c657685306d8e1478a45e9303ddcd8ac5fed5bd52ad4ae0b69b", - "sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c", - "sha256:ec39698c45b11d9694a1b635a70946a5bad066b593af863460a8e600f0dff1ca", - "sha256:ed9aba6e01ff6f2e8285e5aa4154e2970068fe0fc0998c4380d0e6278222269b", - "sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18", - "sha256:ee82c98bed9d97cd2f53bdb035e619309a098ea53ce525833e26b93f673bc318", - "sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07", - "sha256:f7d9b87c4c55e3ea8881dfcbf6d61ea6775fffed1fedffaa60bd047d3c08c430", - "sha256:f83df90191d67af5a831da3a33dd7628b02a95450e168785586ed51e6d28943c", - "sha256:fca9433a45f18b7c779d2bae7beeec4f740d28b788b117a48368d95a3233ed83", - "sha256:fd92bbaa2ecdb7864b7600dcdb6f2f1db6e0346ed425fbd01085be04c63f0b05" - ], - "version": "==0.24.0" + "sha256:0179252846be03fa97d4d5f8233d1c620ef004855f0717712ae1c558f1974a16", + "sha256:06ce08549e49ba69ccc36fc5659a3d0ff4e3a07d542b895b8a9013fcab46c2dc", + "sha256:0b90651b4cf9e158d01faa0833b073e2e37719264bcee3eac49fc3c74e7d304b", + "sha256:0d1ec043f02ca04bf21b1b32cab155ce90c651aaf5540db8eb8ad7f7e645cba8", + "sha256:0fe4e740ea94978b2b2ab308cbf9270a246bcbb44401f77cc8740348cbaeac3d", + "sha256:127de3883bdb29dbd3b21f63126bb8fa6e773b74eaef46521025a9ce390e1073", + "sha256:1550be1a5cb3be08a3fb84636eaafa9b7119b70c71b0bed48726fd1d5aa9b868", + "sha256:160eff7d1267d7b025e983ca8460e8cc67b328284967cbe29c05f3c3163711a3", + "sha256:16db2d7e12f94818cbf16d4c8938e4d8aaecee23826344addfaaa671a1527b07", + "sha256:1c6cf7709ed3e55704cc06f6e835bf43c03bc8e3cb8ff946bf69a2e0a78d9d77", + "sha256:1da46bb1eefb5a37a8fb6fd52ad5d14822d67c498d99bda8754222396164ae42", + "sha256:1df924ba82ae9e77340101c28d56cbaff2c991bd6fe8444a545d24075abb0a87", + "sha256:1e263cc718545b7f897baeac1f00299ab6fabe3e18caaacacb0edf6d5f35513c", + "sha256:228e2247de583475d4cebf6b9af5dc9918abb99d1ef5ee737155bb39fb33f3c0", + "sha256:275c1b0e942d335fccb6014d79267d1b9fa45b5ac0639c297f1e856f2f532552", + "sha256:29b9cb35b7f290db1c31fb2fdf8fc6d3730cfa4bca4b49761083307f441cac5a", + "sha256:2b4691234d31686dca133c920f94e478b548a8e7c750f28dbbc2e4333e0d3da9", + "sha256:2b961b86cd3973f5822826017cad7f5a75795168cb645c3a6b30c349094e02e3", + "sha256:2dcc3f60c445f8ce14156854a072ceb36b83807ed803d37fdea2a50e898635d6", + "sha256:2f492d2907263d6d0d52f897a68647195bc093dafed14508a8d6817973586b6b", + "sha256:310505ad305e30cb6c5f55945858cdbe0eb297fc57378f29bacceb534ac34199", + "sha256:34e87c7b3464d02af87f1059fedda5484e43b153ef519e4085fe1a03dd94801e", + "sha256:418c5ce332f74939ff60691e5293e27c206c8164ce2b8ce0d9abf013003fb7fe", + "sha256:46e86ed457c3486080a72bc837300dd200e18d08183f12b6ca63475ab64ed651", + "sha256:48681c86f2cb08348631fed788a116c89c787fdf1e6381c5febafd782f6c3b44", + "sha256:489b80812f52a8d8c7b0d10f0d956db0efed25df2821c7a934f6143f76938bd6", + "sha256:48c9f3bc90c556a854f4cab6a79c16974099ccfa3e3e150673d82d47a4bc92c9", + "sha256:49bc1bc26abf4f32e132652f4b3bfeec77d8f8f62f57652703ef127e85a3e38d", + "sha256:52bb50a4c4ca2a689fdba84ba8ecc6a4e6210f03b6af93181bb61c4ec3abaf86", + "sha256:5691340f259b8f76b45fb31b98e594d46c36d1dc8285efa7975f7f50230c9093", + "sha256:62691f1c0894b001c7cde1195c03b7801aaa794a837bd6eef24da87d1542838d", + "sha256:632a52dcaee44792d0965c17bdfe5dc0edad5b86d6a29e53d6ad4bf92dc0ff49", + "sha256:65ab1fb635476f6170b07e8e21db0424de94877e4b76b7feabfe11f9a5fc12b5", + "sha256:6a5bc3ca468bb58a2ef50441f953e1f77b9a61bd1b8c347c8223403dc9b4ac9a", + "sha256:6a76494d2c5311584f22416c5a87c1e2cb954ff9b5f0988027bc4ef2a8a67181", + "sha256:6f8dc09ae69af50bead60783180f656ad96bd33ffbf6e7a6fce900f6d53b08f1", + "sha256:703aa5e50e465be901e0e0f9d5739add15e696d8c26c53bc6fc00eb65d7b9469", + "sha256:713f67132346bdcb4c12df185c30cf04bdf4bf6ea3acbc3ace0912cab6b7cb8c", + "sha256:75d3bcfa90454dba8df12adc86b13b6d85fda97d90e708efc036c2760cc6ba44", + "sha256:7ca05cacf2e5c4a97d02a2878a24020daca21dbb8823b023b978210a75c79098", + "sha256:80bf4b459d94a0387617a1b499f314aa04d8a64b7a0747d15d425b8c8b151da0", + "sha256:84fac88278f42d61c519a6c75fb5296fd56710b05bbdcc74bdf85db409a03780", + "sha256:889a37e2acf43c377b5124166bece139b4c731b61492ab22e64d371cce0e6e80", + "sha256:8af4b582d5fc1b8465d1d2483e5e7b880cc1a4e99f6ff65c23d64d070867ac58", + "sha256:90b0fe1fcea9bd6e3084b44875e179b4adcc4057a3b81402658d0eb58c98edf8", + "sha256:93436ed550e429da007fbafb723e0769f25bae178fbb287a94cb4ccdf42d3af3", + "sha256:995c374e86fa82126c03c5b4630c4e312327ecfe27761accb25b5e1d7ab50ec8", + "sha256:9af037d3df7188ae21dc1c7624501f2f90d81be6550904e07869d8d0e6766655", + "sha256:9e080cf917b35b20c889225a13f290f2716748362f6071b859b60b8847a6aa43", + "sha256:a2ec98e31e1844eac860e70d9247db9d75440fc8f5f679c37d01914568d18721", + "sha256:abd85de513eb83f5ec153a802348e7a5baa4588b818043848247e3e8986094e8", + "sha256:ac1be85fe43b4bf9a251978ce5c3bb30e1ada9784290441f5423a28633a958a7", + "sha256:be37f9b1f8934cd9e7eccfcb5612af9fb728fecbe16248b082b709a9d1b348bf", + "sha256:bfcae6aecd9e0cb425f5145afee871465b98b75862e038d42fe91fd753ddd780", + "sha256:c05b021f7b5aa333124f2a64d56e4cb9963b6efdf44e8d819152237bbd93ba15", + "sha256:c14a07bdb475eb696f85c715dbd0f037918ccbb5248290448488a0b4ef201aad", + "sha256:c18f3502ad0737813c7dad70e3e1cc966cc147fbaeef47a09463bbffe70b0a00", + "sha256:c2e9fe695ff151b42ab06501820f40d01310fbd58ba24da8923ace79cf6d702d", + "sha256:c68be72b1666d93b266714f2d4092d78dc53bd11cf91ed5a3c16527587a52e29", + "sha256:ca94c85911601b097d53caeeec30201736ad69a93f30d15672b967558df02885", + "sha256:cf745cbfad6389c0e331786e5fe9ae3f06e9d9c2ce2432378e1267954793975c", + "sha256:d9dd2b89a16cf7ab9c1170b5863e68de6bf83db51544875b25a5f05a7269e678", + "sha256:ddff3f8b9fa24a60527c137c852d0d9a7da2a02cf2151650029fdc97c852c974", + "sha256:e153a690b7255c5ced17895394b4f109d5dcc2a4f35cb809374da50f0e5c456a", + "sha256:ea2b51c5f38bad812da2ec0cd7eec09d25f521a8b6b6843cbccedd9a1d8a5c15", + "sha256:ef9ec8068cf23458dbf36a08e0c16f0a2df04b42a8827619646637be1769300a", + "sha256:f280b02827adc9d87f764972fbeb701cf5611f80b619c20568e1982a277d6146", + "sha256:f3ff7da165c99a5412fe5dd2304dd2dbaaaa5da718aad942dcb3a178eaa70c56", + "sha256:f58d3bfafecf3d81c15d99fc0ecf4319e80ac712c77cf0ce2661c8cf8bf84066", + "sha256:f79fe7993e230a12172ce7d7c7db061f046f672f2b946431c81aff8f60b2758b", + "sha256:ffe709b1d0bc2e9921257569675674cafb3a5f8af689ab9f3f2b3f88775b960f" + ], + "markers": "python_version >= '3.9'", + "version": "==1.0.3" }, "wcwidth": { "hashes": [ @@ -4251,94 +4260,78 @@ }, "websockets": { "hashes": [ - "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", - "sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54", - "sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23", - "sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7", - "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", - "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", - "sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf", - "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", - "sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e", - "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", - "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", - "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", - "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", - "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", - "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", - "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", - "sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978", - "sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20", - "sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295", - "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", - "sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6", - "sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb", - "sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a", - "sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa", - "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", - "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", - "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", - "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", - "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", - "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", - "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", - "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", - "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", - "sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79", - "sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96", - "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", - "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", - "sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842", - "sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa", - "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", - "sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d", - "sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51", - "sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7", - "sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09", - "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", - "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", - "sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b", - "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", - "sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678", - "sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea", - "sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d", - "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", - "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", - "sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5", - "sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027", - "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", - "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", - "sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c", - "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", - "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", - "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", - "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", - "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", - "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", - "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", - "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", - "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", - "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", - "sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d", - "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", - "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", - "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", - "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", - "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", - "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", - "sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7", - "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", - "sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c", - "sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17", - "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", - "sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db", - "sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6", - "sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d", - "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", - "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", - "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6" - ], - "version": "==13.1" + "sha256:00fe5da3f037041da1ee0cf8e308374e236883f9842c7c465aa65098b1c9af59", + "sha256:01bb2d4f0a6d04538d3c5dfd27c0643269656c28045a53439cbf1c004f90897a", + "sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb", + "sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e", + "sha256:0d4290d559d68288da9f444089fd82490c8d2744309113fc26e2da6e48b65da6", + "sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10", + "sha256:14839f54786987ccd9d03ed7f334baec0f02272e7ec4f6e9d427ff584aeea8b4", + "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0", + "sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0", + "sha256:205f672a6c2c671a86d33f6d47c9b35781a998728d2c7c2a3e1cf3333fcb62b7", + "sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250", + "sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078", + "sha256:25225cc79cfebc95ba1d24cd3ab86aaa35bcd315d12fa4358939bd55e9bd74a5", + "sha256:3630b670d5057cd9e08b9c4dab6493670e8e762a24c2c94ef312783870736ab9", + "sha256:368a05465f49c5949e27afd6fbe0a77ce53082185bbb2ac096a3a8afaf4de52e", + "sha256:36ebd71db3b89e1f7b1a5deaa341a654852c3518ea7a8ddfdf69cc66acc2db1b", + "sha256:39450e6215f7d9f6f7bc2a6da21d79374729f5d052333da4d5825af8a97e6735", + "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8", + "sha256:3c3deac3748ec73ef24fc7be0b68220d14d47d6647d2f85b2771cb35ea847aa1", + "sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0", + "sha256:3fc753451d471cff90b8f467a1fc0ae64031cf2d81b7b34e1811b7e2691bc4bc", + "sha256:414ffe86f4d6f434a8c3b7913655a1a5383b617f9bf38720e7c0799fac3ab1c6", + "sha256:449d77d636f8d9c17952628cc7e3b8faf6e92a17ec581ec0c0256300717e1512", + "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4", + "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e", + "sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d", + "sha256:5b918d288958dc3fa1c5a0b9aa3256cb2b2b84c54407f4813c45d52267600cd3", + "sha256:5ef440054124728cc49b01c33469de06755e5a7a4e83ef61934ad95fc327fbb0", + "sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7", + "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058", + "sha256:6d24fc337fc055c9e83414c94e1ee0dee902a486d19d2a7f0929e49d7d604b09", + "sha256:7048eb4415d46368ef29d32133134c513f507fff7d953c18c91104738a68c3b3", + "sha256:77569d19a13015e840b81550922056acabc25e3f52782625bc6843cfa034e1da", + "sha256:8149a0f5a72ca36720981418eeffeb5c2729ea55fa179091c81a0910a114a5d2", + "sha256:836bef7ae338a072e9d1863502026f01b14027250a4545672673057997d5c05a", + "sha256:8621a07991add373c3c5c2cf89e1d277e49dc82ed72c75e3afc74bd0acc446f0", + "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d", + "sha256:88cf9163ef674b5be5736a584c999e98daf3aabac6e536e43286eb74c126b9c7", + "sha256:8fda642151d5affdee8a430bd85496f2e2517be3a2b9d2484d633d5712b15c56", + "sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179", + "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f", + "sha256:9481a6de29105d73cf4515f2bef8eb71e17ac184c19d0b9918a3701c6c9c4f23", + "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199", + "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a", + "sha256:a032855dc7db987dff813583d04f4950d14326665d7e714d584560b140ae6b8b", + "sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29", + "sha256:a35f704be14768cea9790d921c2c1cc4fc52700410b1c10948511039be824aac", + "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58", + "sha256:a4c805c6034206143fbabd2d259ec5e757f8b29d0a2f0bf3d2fe5d1f60147a4a", + "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45", + "sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434", + "sha256:b1f3628a0510bd58968c0f60447e7a692933589b791a6b572fcef374053ca280", + "sha256:b7e7ea2f782408c32d86b87a0d2c1fd8871b0399dd762364c731d86c86069a78", + "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707", + "sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58", + "sha256:cc1fc87428c1d18b643479caa7b15db7d544652e5bf610513d4a3478dbe823d0", + "sha256:cd7c11968bc3860d5c78577f0dbc535257ccec41750675d58d8dc66aa47fe52c", + "sha256:ceada5be22fa5a5a4cdeec74e761c2ee7db287208f54c718f2df4b7e200b8d4a", + "sha256:cf5201a04550136ef870aa60ad3d29d2a59e452a7f96b94193bee6d73b8ad9a9", + "sha256:d9fd19ecc3a4d5ae82ddbfb30962cf6d874ff943e56e0c81f5169be2fda62979", + "sha256:ddaa4a390af911da6f680be8be4ff5aaf31c4c834c1a9147bc21cbcbca2d4370", + "sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098", + "sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e", + "sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8", + "sha256:e7591d6f440af7f73c4bd9404f3772bfee064e639d2b6cc8c94076e71b2471c1", + "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05", + "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed", + "sha256:f6cf0ad281c979306a6a34242b371e90e891bce504509fb6bb5246bbbf31e7b6", + "sha256:f95ba34d71e2fa0c5d225bde3b3bdb152e957150100e75c86bc7f3964c450d89" + ], + "markers": "python_version >= '3.9'", + "version": "==14.1" }, "whitenoise": { "extras": [ @@ -4353,79 +4346,74 @@ }, "wrapt": { "hashes": [ - "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc", - "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81", - "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09", - "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e", - "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", - "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", - "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", - "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487", - "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40", - "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c", - "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060", - "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", - "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41", - "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9", - "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b", - "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", - "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", - "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362", - "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00", - "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc", - "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", - "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", - "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956", - "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966", - "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1", - "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228", - "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72", - "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d", - "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292", - "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0", - "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", - "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36", - "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c", - "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5", - "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", - "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73", - "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b", - "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", - "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593", - "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39", - "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389", - "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf", - "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf", - "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89", - "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c", - "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", - "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f", - "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440", - "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465", - "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136", - "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b", - "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", - "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3", - "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8", - "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", - "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e", - "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", - "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c", - "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", - "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8", - "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2", - "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020", - "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35", - "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d", - "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3", - "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", - "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809", - "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d", - "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", - "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" + "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d", + "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301", + "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635", + "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a", + "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed", + "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721", + "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801", + "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b", + "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1", + "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88", + "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8", + "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0", + "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f", + "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578", + "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7", + "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045", + "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada", + "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d", + "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b", + "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a", + "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977", + "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea", + "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346", + "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13", + "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22", + "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339", + "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9", + "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181", + "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c", + "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90", + "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a", + "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489", + "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f", + "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504", + "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea", + "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569", + "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4", + "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce", + "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab", + "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a", + "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f", + "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c", + "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9", + "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf", + "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d", + "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627", + "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d", + "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4", + "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c", + "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d", + "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad", + "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b", + "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33", + "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371", + "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1", + "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393", + "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106", + "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df", + "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379", + "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451", + "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b", + "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575", + "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed", + "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb", + "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838" ], - "markers": "python_version >= '3.6'", - "version": "==1.16.0" + "markers": "python_version >= '3.8'", + "version": "==1.17.0" }, "xlsxwriter": { "hashes": [ @@ -4436,91 +4424,91 @@ }, "yarl": { "hashes": [ - "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac", - "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", - "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91", - "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5", - "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df", - "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3", - "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463", - "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b", - "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5", - "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74", - "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3", - "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3", - "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4", - "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0", - "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299", - "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2", - "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac", - "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61", - "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931", - "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21", - "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3", - "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7", - "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96", - "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f", - "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243", - "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857", - "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f", - "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca", - "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488", - "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da", - "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948", - "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5", - "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934", - "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473", - "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7", - "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685", - "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e", - "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147", - "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71", - "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67", - "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04", - "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822", - "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11", - "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6", - "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0", - "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec", - "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda", - "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556", - "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4", - "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c", - "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f", - "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8", - "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba", - "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258", - "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95", - "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383", - "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e", - "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938", - "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374", - "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55", - "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139", - "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17", - "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217", - "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d", - "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d", - "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe", - "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199", - "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d", - "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8", - "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c", - "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29", - "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172", - "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860", - "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7", - "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170", - "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138", - "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06", - "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004", - "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159", - "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da", - "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988", - "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75" + "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba", + "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193", + "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318", + "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee", + "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e", + "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1", + "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a", + "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186", + "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1", + "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50", + "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640", + "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb", + "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8", + "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc", + "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5", + "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58", + "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2", + "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393", + "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24", + "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b", + "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910", + "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c", + "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272", + "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed", + "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1", + "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04", + "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d", + "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5", + "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d", + "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889", + "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae", + "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b", + "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c", + "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576", + "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34", + "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477", + "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990", + "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2", + "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512", + "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069", + "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a", + "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6", + "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0", + "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8", + "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb", + "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa", + "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8", + "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e", + "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e", + "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985", + "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8", + "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1", + "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5", + "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690", + "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10", + "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789", + "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b", + "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca", + "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e", + "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5", + "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59", + "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9", + "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8", + "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db", + "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde", + "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7", + "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb", + "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3", + "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6", + "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285", + "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb", + "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8", + "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482", + "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd", + "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75", + "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760", + "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782", + "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53", + "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2", + "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1", + "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719", + "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62" ], "markers": "python_version >= '3.9'", - "version": "==1.17.1" + "version": "==1.18.3" }, "zope.event": { "hashes": [ @@ -4532,46 +4520,46 @@ }, "zope.interface": { "hashes": [ - "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f", - "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e", - "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616", - "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3", - "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67", - "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8", - "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b", - "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585", - "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446", - "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd", - "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a", - "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3", - "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c", - "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853", - "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f", - "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5", - "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8", - "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501", - "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd", - "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029", - "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e", - "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f", - "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580", - "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c", - "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9", - "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0", - "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2", - "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d", - "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73", - "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16", - "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a", - "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267", - "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b", - "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d", - "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053", - "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25", - "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770" + "sha256:033b3923b63474800b04cba480b70f6e6243a62208071fc148354f3f89cc01b7", + "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a", + "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7", + "sha256:0ef9e2f865721553c6f22a9ff97da0f0216c074bd02b25cf0d3af60ea4d6931d", + "sha256:1090c60116b3da3bfdd0c03406e2f14a1ff53e5771aebe33fec1edc0a350175d", + "sha256:144964649eba4c5e4410bb0ee290d338e78f179cdbfd15813de1a664e7649b3b", + "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d", + "sha256:1909f52a00c8c3dcab6c4fad5d13de2285a4b3c7be063b239b8dc15ddfb73bd2", + "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465", + "sha256:224b7b0314f919e751f2bca17d15aad00ddbb1eadf1cb0190fa8175edb7ede62", + "sha256:25e6a61dcb184453bb00eafa733169ab6d903e46f5c2ace4ad275386f9ab327a", + "sha256:27f926f0dcb058211a3bb3e0e501c69759613b17a553788b2caeb991bed3b61d", + "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5", + "sha256:2ad9913fd858274db8dd867012ebe544ef18d218f6f7d1e3c3e6d98000f14b75", + "sha256:31d06db13a30303c08d61d5fb32154be51dfcbdb8438d2374ae27b4e069aac40", + "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98", + "sha256:3f6771d1647b1fc543d37640b45c06b34832a943c80d1db214a37c31161a93f1", + "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd", + "sha256:52e446f9955195440e787596dccd1411f543743c359eeb26e9b2c02b077b0519", + "sha256:550f1c6588ecc368c9ce13c44a49b8d6b6f3ca7588873c679bd8fd88a1b557b6", + "sha256:72cd1790b48c16db85d51fbbd12d20949d7339ad84fd971427cf00d990c1f137", + "sha256:7bd449c306ba006c65799ea7912adbbfed071089461a19091a228998b82b1fdb", + "sha256:7dc5016e0133c1a1ec212fc87a4f7e7e562054549a99c73c8896fa3a9e80cbc7", + "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c", + "sha256:80ecf2451596f19fd607bb09953f426588fc1e79e93f5968ecf3367550396b22", + "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe", + "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54", + "sha256:a102424e28c6b47c67923a1f337ede4a4c2bba3965b01cf707978a801fc7442c", + "sha256:a19a6cc9c6ce4b1e7e3d319a473cf0ee989cbbe2b39201d7c19e214d2dfb80c7", + "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b", + "sha256:baf95683cde5bc7d0e12d8e7588a3eb754d7c4fa714548adcd96bdf90169f021", + "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d", + "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2", + "sha256:d3a8ffec2a50d8ec470143ea3d15c0c52d73df882eef92de7537e8ce13475e8a", + "sha256:e204937f67b28d2dca73ca936d3039a144a081fc47a07598d44854ea2a106239", + "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398", + "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89" ], "markers": "python_version >= '3.8'", - "version": "==7.1.1" + "version": "==7.2" }, "zstandard": { "hashes": [ @@ -4689,11 +4677,11 @@ }, "attrs": { "hashes": [ - "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", - "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2" + "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", + "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308" ], - "markers": "python_version >= '3.7'", - "version": "==24.2.0" + "markers": "python_version >= '3.8'", + "version": "==24.3.0" }, "babel": { "hashes": [ @@ -4745,19 +4733,19 @@ "pytest" ], "hashes": [ - "sha256:5d02ead62715ab4061cd3b07562db898a976badc274d88743e6f00f6e3093e98", - "sha256:ad7a213739531a4493a5ea8190ad4752c42f228f47d86940133d7f63b168a299" + "sha256:006d641ff97a5a514b0b16776fd24fad2ed4086407b10ae146061fb0ac4b980f", + "sha256:afae38000931f976644eab8c679fb1e9e815d57e5452f225135d5e3b1285615a" ], "markers": "python_version >= '3.11'", - "version": "==1.1.1" + "version": "==1.3.1" }, "certifi": { "hashes": [ - "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", + "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db" ], "markers": "python_version >= '3.6'", - "version": "==2024.8.30" + "version": "==2024.12.14" }, "cfgv": { "hashes": [ @@ -4769,122 +4757,109 @@ }, "charset-normalizer": { "hashes": [ - "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", - "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", - "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", - "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", - "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", - "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", - "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", - "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", - "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", - "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", - "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", - "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", - "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", - "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", - "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", - "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", - "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", - "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", - "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", - "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", - "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", - "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", - "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", - "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", - "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", - "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", - "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", - "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", - "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", - "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", - "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", - "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", - "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", - "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", - "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", - "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", - "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", - "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", - "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", - "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", - "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", - "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", - "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", - "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", - "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", - "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", - "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", - "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", - "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", - "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", - "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", - "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", - "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", - "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", - "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", - "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", - "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", - "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", - "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", - "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", - "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", - "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", - "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", - "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", - "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", - "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", - "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", - "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", - "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", - "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", - "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", - "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", - "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", - "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", - "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", - "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", - "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", - "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", - "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", - "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", - "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", - "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", - "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", - "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", - "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", - "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", - "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", - "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", - "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", - "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", - "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", - "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", - "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", - "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", - "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b", - "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", - "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", - "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4", - "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", - "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", - "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a", - "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748", - "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", - "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", - "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482" + "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", + "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616" ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.4.0" + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "click": { "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" + "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", + "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" ], "markers": "python_version >= '3.7'", - "version": "==8.1.7" + "version": "==8.1.8" }, "colorama": { "hashes": [ @@ -4899,81 +4874,80 @@ "toml" ], "hashes": [ - "sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376", - "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", - "sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111", - "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", - "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", - "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", - "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", - "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", - "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", - "sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c", - "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", - "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", - "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", - "sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0", - "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", - "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", - "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", - "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", - "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", - "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", - "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", - "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", - "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", - "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", - "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", - "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", - "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", - "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", - "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", - "sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901", - "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", - "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", - "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", - "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", - "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", - "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", - "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", - "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", - "sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3", - "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", - "sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076", - "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", - "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", - "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", - "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", - "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", - "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", - "sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09", - "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", - "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", - "sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f", - "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", - "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", - "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", - "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", - "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", - "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", - "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", - "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", - "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", - "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", - "sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858" + "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", + "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f", + "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", + "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", + "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", + "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", + "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", + "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", + "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", + "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", + "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", + "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", + "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", + "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", + "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", + "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59", + "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", + "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18", + "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", + "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", + "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", + "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", + "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", + "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", + "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90", + "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", + "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a", + "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", + "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", + "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", + "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", + "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", + "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", + "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d", + "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", + "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", + "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", + "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", + "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", + "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", + "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", + "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", + "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", + "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4", + "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25", + "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", + "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", + "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", + "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", + "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315", + "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", + "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", + "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27", + "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", + "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", + "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", + "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", + "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", + "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", + "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", + "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", + "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==7.6.4" + "version": "==7.6.10" }, "coveralls": { "hashes": [ - "sha256:7a6b1fa9848332c7b2221afb20f3df90272ac0167060f41b5fe90429b30b1809", - "sha256:7b2a0a2bcef94f295e3cf28dcc55ca40b71c77d1c2446b538e85f0f7bc21aa69" + "sha256:a8de28a5f04e418c7142b8ce6588c3a64245b433c458a5871cb043383667e4f2", + "sha256:c5e50b73b980d89308816b597e3e7bdeb0adedf831585d5c4ac967d576f8925d" ], "index": "pypi", - "markers": "python_version < '3.13' and python_version >= '3.8'", - "version": "==4.0.1" + "version": "==1.8.0" }, "distlib": { "hashes": [ @@ -4984,11 +4958,11 @@ }, "django": { "hashes": [ - "sha256:bd7376f90c99f96b643722eee676498706c9fd7dc759f55ebfaf2c08ebcdf4f0", - "sha256:f11aa87ad8d5617171e3f77e1d5d16f004b79a2cf5d2e1d2b97a6a1f8e9ba5ed" + "sha256:236e023f021f5ce7dee5779de7b286565fdea5f4ab86bae5338e3f7b69896cf0", + "sha256:de450c09e91879fa5a307f696e57c851955c910a438a35e6b4c895e86bedc82a" ], "markers": "python_version >= '3.10'", - "version": "==5.1.2" + "version": "==5.1.4" }, "django-stubs": { "hashes": [ @@ -5009,12 +4983,12 @@ }, "djangorestframework-stubs": { "hashes": [ - "sha256:34539871895d66d382b6ae3655d9f95c1de7733cf50bc29097638d367ed3117d", - "sha256:79dc9018f5d5fa420f9981eec9f1e820ecbd04719791f144419cdc6c5b8e29bd" + "sha256:0e72f1e8507bdb2acd99b304520494ea5d45bccba51a4877140cb65fd461adf0", + "sha256:3df129845acac6c1b097bc7e5b360d53e32a02029d60b4f972dfbd3e2508f236" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==3.15.1" + "markers": "python_version >= '3.9'", + "version": "==3.15.2" }, "docopt": { "hashes": [ @@ -5049,12 +5023,12 @@ }, "flake8-bugbear": { "hashes": [ - "sha256:435b531c72b27f8eff8d990419697956b9fd25c6463c5ba98b3991591de439db", - "sha256:cccf786ccf9b2e1052b1ecfa80fb8f80832d0880425bcbd4cd45d3c8128c2683" + "sha256:1b6967436f65ca22a42e5373aaa6f2d87966ade9aa38d4baf2a1be550767545e", + "sha256:46273cef0a6b6ff48ca2d69e472f41420a42a46e24b2a8972e4f0d6733d12a64" ], "index": "pypi", "markers": "python_full_version >= '3.8.1'", - "version": "==24.10.31" + "version": "==24.12.12" }, "flake8-docstrings": { "hashes": [ @@ -5067,47 +5041,47 @@ }, "gevent": { "hashes": [ - "sha256:051b22e2758accfddb0457728bfc9abf8c3f2ce6bca43f1ff6e07b5ed9e49bf4", - "sha256:0de6eb3d55c03138fda567d9bfed28487ce5d0928c5107549767a93efdf2be26", - "sha256:18e6984ec96fc95fd67488555c38ece3015be1f38b1bcceb27b7d6c36b343008", - "sha256:1c3a828b033fb02b7c31da4d75014a1f82e6c072fc0523456569a57f8b025861", - "sha256:1ce6dab94c0b0d24425ba55712de2f8c9cb21267150ca63f5bb3a0e1f165da99", - "sha256:1e24ffea72e27987979c009536fd0868e52239b44afe6cf7135ce8aafd0f108e", - "sha256:26ca7a6b42d35129617025ac801135118333cad75856ffc3217b38e707383eba", - "sha256:34aea15f9c79f27a8faeaa361bc1e72c773a9b54a1996a2ec4eefc8bcd59a824", - "sha256:385710355eadecdb70428a5ae3e7e5a45dcf888baa1426884588be9d25ac4290", - "sha256:3ac83b74304487afa211a01909c7dd257e574db0cd429d866c298e21df7aeedf", - "sha256:3ad8fb70aa0ebc935729c9699ac31b210a49b689a7b27b7ac9f91676475f3f53", - "sha256:40ea3e40e8bb4fdb143c2a8edf2ccfdebd56016c7317c341ce8094c7bee08818", - "sha256:57a5c4e0bdac482c5f02f240d0354e61362df73501ef6ebafce8ef635cad7527", - "sha256:5d850a453d66336272be4f1d3a8126777f3efdaea62d053b4829857f91e09755", - "sha256:68c3a0d8402755eba7f69022e42e8021192a721ca8341908acc222ea597029b6", - "sha256:7021e26d70189b33c27173d4173f27bf4685d6b6f1c0ea50e5335f8491cb110c", - "sha256:70e9ed7ecb70e0df7dc97c3bc420de9a45a7c76bd5861c6cfec8c549700e681e", - "sha256:89c4115e3f5ada55f92b61701a46043fe42f702b5af863b029e4c1a76f6cc2d4", - "sha256:8af65a4d4feaec6042c666d22c322a310fba3b47e841ad52f724b9c3ce5da48e", - "sha256:8e58ee3723f1fbe07d66892f1caa7481c306f653a6829b6fd16cb23d618a5915", - "sha256:9ca2266e08f43c0e22c028801dff7d92a0b102ef20e4caeb6a46abfb95f6a328", - "sha256:9e1210334a9bc9f76c3d008e0785ca62214f8a54e1325f6c2ecab3b6a572a015", - "sha256:a9a89d6e396ef6f1e3968521bf56e8c4bee25b193bbf5d428b7782d582410822", - "sha256:aa7ee1bd5cabb2b7ef35105f863b386c8d5e332f754b60cfc354148bd70d35d1", - "sha256:b52382124eca13135a3abe4f65c6bd428656975980a48e51b17aeab68bdb14db", - "sha256:c1d80090485da1ea3d99205fe97908b31188c1f4857f08b333ffaf2de2e89d18", - "sha256:ce417bcaaab496bc9c77f75566531e9d93816262037b8b2dbb88b0fdcd66587c", - "sha256:d67daed8383326dc8b5e58d88e148d29b6b52274a489e383530b0969ae7b9cb9", - "sha256:d758f0d4dbf32502ec87bb9b536ca8055090a16f8305f0ada3ce6f34e70f2fd7", - "sha256:d7a1ad0f2da582f5bd238bca067e1c6c482c30c15a6e4d14aaa3215cbb2232f3", - "sha256:e534e6a968d74463b11de6c9c67f4b4bf61775fb00f2e6e0f7fcdd412ceade18", - "sha256:eb5edb6433764119a664bbb148d2aea9990950aa89cc3498f475c2408d523ea3", - "sha256:f0c129f81d60cda614acb4b0c5731997ca05b031fb406fcb58ad53a7ade53b13", - "sha256:f147e38423fbe96e8731f60a63475b3d2cab2f3d10578d8ee9d10c507c58a2ff", - "sha256:f18689f7a70d2ed0e75bad5036ec3c89690a493d4cfac8d7cdb258ac04b132bd", - "sha256:f2ae3efbbd120cdf4a68b7abc27a37e61e6f443c5a06ec2c6ad94c37cd8471ec", - "sha256:f4e526fdc279c655c1e809b0c34b45844182c2a6b219802da5e411bd2cf5a8ad", - "sha256:f7f4f171d4d2018170454d84c934842e1b5f6ce7468ba298f6e7f7cff15000a3" + "sha256:1c3443b0ed23dcb7c36a748d42587168672953d368f2956b17fad36d43b58836", + "sha256:1d4fadc319b13ef0a3c44d2792f7918cf1bca27cacd4d41431c22e6b46668026", + "sha256:1ea50009ecb7f1327347c37e9eb6561bdbc7de290769ee1404107b9a9cba7cf1", + "sha256:2142704c2adce9cd92f6600f371afb2860a446bfd0be5bd86cca5b3e12130766", + "sha256:351d1c0e4ef2b618ace74c91b9b28b3eaa0dd45141878a964e03c7873af09f62", + "sha256:356b73d52a227d3313f8f828025b665deada57a43d02b1cf54e5d39028dbcf8d", + "sha256:3d882faa24f347f761f934786dde6c73aa6c9187ee710189f12dcc3a63ed4a50", + "sha256:58851f23c4bdb70390f10fc020c973ffcf409eb1664086792c8b1e20f25eef43", + "sha256:68bee86b6e1c041a187347ef84cf03a792f0b6c7238378bf6ba4118af11feaae", + "sha256:7398c629d43b1b6fd785db8ebd46c0a353880a6fab03d1cf9b6788e7240ee32e", + "sha256:816b3883fa6842c1cf9d2786722014a0fd31b6312cca1f749890b9803000bad6", + "sha256:81d918e952954675f93fb39001da02113ec4d5f4921bf5a0cc29719af6824e5d", + "sha256:85329d556aaedced90a993226d7d1186a539c843100d393f2349b28c55131c85", + "sha256:8619d5c888cb7aebf9aec6703e410620ef5ad48cdc2d813dd606f8aa7ace675f", + "sha256:8bd1419114e9e4a3ed33a5bad766afff9a3cf765cb440a582a1b3a9bc80c1aca", + "sha256:92e0d7759de2450a501effd99374256b26359e801b2d8bf3eedd3751973e87f5", + "sha256:92fe5dfee4e671c74ffaa431fd7ffd0ebb4b339363d24d0d944de532409b935e", + "sha256:97e2f3999a5c0656f42065d02939d64fffaf55861f7d62b0107a08f52c984897", + "sha256:9d3b249e4e1f40c598ab8393fc01ae6a3b4d51fc1adae56d9ba5b315f6b2d758", + "sha256:a3d75fa387b69c751a3d7c5c3ce7092a171555126e136c1d21ecd8b50c7a6e46", + "sha256:a5f1701ce0f7832f333dd2faf624484cbac99e60656bfbb72504decd42970f0f", + "sha256:b24d800328c39456534e3bc3e1684a28747729082684634789c2f5a8febe7671", + "sha256:b5efe72e99b7243e222ba0c2c2ce9618d7d36644c166d63373af239da1036bab", + "sha256:b7bfcfe08d038e1fa6de458891bca65c1ada6d145474274285822896a858c870", + "sha256:beede1d1cff0c6fafae3ab58a0c470d7526196ef4cd6cc18e7769f207f2ea4eb", + "sha256:c6b775381f805ff5faf250e3a07c0819529571d19bb2a9d474bee8c3f90d66af", + "sha256:c9c935b83d40c748b6421625465b7308d87c7b3717275acd587eef2bd1c39546", + "sha256:ca845138965c8c56d1550499d6b923eb1a2331acfa9e13b817ad8305dde83d11", + "sha256:d618e118fdb7af1d6c1a96597a5cd6ac84a9f3732b5be8515c6a66e098d498b6", + "sha256:d6c0a065e31ef04658f799215dddae8752d636de2bed61365c358f9c91e7af61", + "sha256:d740206e69dfdfdcd34510c20adcb9777ce2cc18973b3441ab9767cd8948ca8a", + "sha256:d7886b63ebfb865178ab28784accd32f287d5349b3ed71094c86e4d3ca738af5", + "sha256:d9347690f4e53de2c4af74e62d6fabc940b6d4a6cad555b5a379f61e7d3f2a8e", + "sha256:d9ca80711e6553880974898d99357fb649e062f9058418a92120ca06c18c3c59", + "sha256:e24181d172f50097ac8fc272c8c5b030149b630df02d1c639ee9f878a470ba2b", + "sha256:ec68e270543ecd532c4c1d70fca020f90aa5486ad49c4f3b8b2e64a66f5c9274", + "sha256:f43f47e702d0c8e1b8b997c00f1601486f9f976f84ab704f8f11536e3fa144c9", + "sha256:ff96c5739834c9a594db0e12bf59cb3fa0e5102fc7b893972118a3166733d61c" ], "markers": "python_version >= '3.9'", - "version": "==24.10.3" + "version": "==24.11.1" }, "ghp-import": { "hashes": [ @@ -5121,19 +5095,19 @@ "grpc" ], "hashes": [ - "sha256:26f8d76b96477db42b55fd02a33aae4a42ec8b86b98b94969b7333a2c828bf35", - "sha256:a6652b6bd51303902494998626653671703c420f6f4c88cfd3f50ed723e9d021" + "sha256:10d82ac0fca69c82a25b3efdeefccf6f28e02ebb97925a8cce8edbfe379929d9", + "sha256:e255640547a597a4da010876d333208ddac417d60add22b6851a0c66a831fcaf" ], "markers": "python_version >= '3.7'", - "version": "==2.22.0" + "version": "==2.24.0" }, "google-api-python-client": { "hashes": [ - "sha256:1a5232e9cfed8c201799d9327e4d44dc7ea7daa3c6e1627fca41aa201539c0da", - "sha256:b9d68c6b14ec72580d66001bd33c5816b78e2134b93ccc5cf8f624516b561750" + "sha256:6352185c505e1f311f11b0b96c1b636dcb0fec82cd04b80ac5a671ac4dcab339", + "sha256:b809c111ded61716a9c1c7936e6899053f13bae3defcdfda904bd2ca68065b9c" ], "markers": "python_version >= '3.7'", - "version": "==2.149.0" + "version": "==2.156.0" }, "google-api-python-client-stubs": { "hashes": [ @@ -5146,20 +5120,20 @@ }, "google-apps-meet": { "hashes": [ - "sha256:282e6c3c8aa49f4a34a6b2ee31c94720801adf200777c7a08f491736de45e4ba", - "sha256:3125f4f8dcdb78f4973a02653540ce6c8c19c4369e2cbed731b7a9f1cbe41d1d" + "sha256:a9c811b7bac7568dea5622ba44005f6bca9ae5d928a68b6f22cd9b8cbc354f74", + "sha256:bfb91f816d679278c80fc079be4cbe3b2f736106697b709a9398d080959730d0" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.1.9" + "version": "==0.1.11" }, "google-auth": { "hashes": [ - "sha256:25df55f327ef021de8be50bad0dfd4a916ad0de96da86cd05661c9297723ad3f", - "sha256:f4c64ed4e01e8e8b646ef34c018f8bf3338df0c8e37d8b3bba40e7f574a3278a" + "sha256:0054623abf1f9c83492c63d3f47e77f0a544caa3d40b2d98e099a611c2dd5d00", + "sha256:42664f18290a6be591be5329a96fe30184be1a1badb7292a7f686a9659de9ca0" ], "markers": "python_version >= '3.7'", - "version": "==2.35.0" + "version": "==2.37.0" }, "google-auth-httplib2": { "hashes": [ @@ -5180,11 +5154,11 @@ }, "googleapis-common-protos": { "hashes": [ - "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63", - "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0" + "sha256:c3e7b33d15fdca5374cc0a7346dd92ffa847425cc4ea941d970f13680052ec8c", + "sha256:d7abcd75fabb2e0ec9f74466401f6c119a0b498e27370e9be4c94cb7e382b8ed" ], "markers": "python_version >= '3.7'", - "version": "==1.65.0" + "version": "==1.66.0" }, "greenlet": { "hashes": [ @@ -5267,80 +5241,80 @@ }, "griffe": { "hashes": [ - "sha256:72964f93e08c553257706d6cd2c42d1c172213feb48b2be386f243380b405d4b", - "sha256:ad6a7980f8c424c9102160aafa3bcdf799df0e75f7829d75af9ee5aef656f860" + "sha256:073e78ad3e10c8378c2f798bd4ef87b92d8411e9916e157fd366a17cc4fd4e52", + "sha256:ed33af890586a5bebc842fcb919fc694b3dc1bc55b7d9e0228de41ce566b4a1d" ], "markers": "python_version >= '3.9'", - "version": "==1.5.1" + "version": "==1.5.4" }, "grpcio": { "hashes": [ - "sha256:01f616a964e540638af5130469451cf580ba8c7329f45ca998ab66e0c7dcdb04", - "sha256:0489063974d1452436139501bf6b180f63d4977223ee87488fe36858c5725292", - "sha256:0e6f255980afef598a9e64a24efce87b625e3e3c80a45162d111a461a9f92955", - "sha256:0f3e49c738396e93b7ba9016e153eb09e0778e776df6090c1b8c91877cc1c426", - "sha256:178f5db771c4f9a9facb2ab37a434c46cb9be1a75e820f187ee3d1e7805c4f65", - "sha256:1a65b503d008f066e994f34f456e0647e5ceb34cfcec5ad180b1b44020ad4970", - "sha256:1d7616d2ded471231c701489190379e0c311ee0a6c756f3c03e6a62b95a7146e", - "sha256:24e8a26dbfc5274d7474c27759b54486b8de23c709d76695237515bc8b5baeab", - "sha256:267d1745894200e4c604958da5f856da6293f063327cb049a51fe67348e4f953", - "sha256:299b3d8c4f790c6bcca485f9963b4846dd92cf6f1b65d3697145d005c80f9fe8", - "sha256:3b6c16489326d79ead41689c4b84bc40d522c9a7617219f4ad94bc7f448c5085", - "sha256:3dc2ed4cabea4dc14d5e708c2b426205956077cc5de419b4d4079315017e9732", - "sha256:43112046864317498a33bdc4797ae6a268c36345a910de9b9c17159d8346602f", - "sha256:4422581cdc628f77302270ff839a44f4c24fdc57887dc2a45b7e53d8fc2376af", - "sha256:4e7b904484a634a0fff132958dabdb10d63e0927398273917da3ee103e8d1f78", - "sha256:5721e66a594a6c4204458004852719b38f3d5522082be9061d6510b455c90afc", - "sha256:5db70d32d6703b89912af16d6d45d78406374a8b8ef0d28140351dd0ec610e98", - "sha256:5ed601c4c6008429e3d247ddb367fe8c7259c355757448d7c1ef7bd4a6739e8e", - "sha256:60336bff760fbb47d7e86165408126f1dded184448e9a4c892189eb7c9d3f90f", - "sha256:608d87d1bdabf9e2868b12338cd38a79969eaf920c89d698ead08f48de9c0f9e", - "sha256:60e6a4dcf5af7bbc36fd9f81c9f372e8ae580870a9e4b6eafe948cd334b81cf3", - "sha256:638354e698fd0c6c76b04540a850bf1db27b4d2515a19fcd5cf645c48d3eb1ed", - "sha256:699e964923b70f3101393710793289e42845791ea07565654ada0969522d0a38", - "sha256:7818c0454027ae3384235a65210bbf5464bd715450e30a3d40385453a85a70cb", - "sha256:786a5b18544622bfb1e25cc08402bd44ea83edfb04b93798d85dca4d1a0b5be5", - "sha256:804c6457c3cd3ec04fe6006c739579b8d35c86ae3298ffca8de57b493524b771", - "sha256:80b866f73224b0634f4312a4674c1be21b2b4afa73cb20953cbbb73a6b36c3cc", - "sha256:85f69fdc1d28ce7cff8de3f9c67db2b0ca9ba4449644488c1e0303c146135ddb", - "sha256:85f862069b86a305497e74d0dc43c02de3d1d184fc2c180993aa8aa86fbd19b8", - "sha256:8a00efecde9d6fcc3ab00c13f816313c040a28450e5e25739c24f432fc6d3c75", - "sha256:8a23cbcc5bb11ea7dc6163078be36c065db68d915c24f5faa4f872c573bb400f", - "sha256:8b0341d66a57f8a3119b77ab32207072be60c9bf79760fa609c5609f2deb1f3f", - "sha256:917e8d8994eed1d86b907ba2a61b9f0aef27a2155bca6cbb322430fc7135b7bb", - "sha256:95b5f2b857856ed78d72da93cd7d09b6db8ef30102e5e7fe0961fe4d9f7d48e8", - "sha256:9e838cad2176ebd5d4a8bb03955138d6589ce9e2ce5d51c3ada34396dbd2dba8", - "sha256:9fd042de4a82e3e7aca44008ee2fb5da01b3e5adb316348c21980f7f58adc311", - "sha256:a25bdea92b13ff4d7790962190bf6bf5c4639876e01c0f3dda70fc2769616335", - "sha256:a6703916c43b1d468d0756c8077b12017a9fcb6a1ef13faf49e67d20d7ebda62", - "sha256:a93deda571a1bf94ec1f6fcda2872dad3ae538700d94dc283c672a3b508ba3af", - "sha256:aa0162e56fd10a5547fac8774c4899fc3e18c1aa4a4759d0ce2cd00d3696ea6b", - "sha256:b49359977c6ec9f5d0573ea4e0071ad278ef905aa74e420acc73fd28ce39e9ce", - "sha256:beee96c8c0b1a75d556fe57b92b58b4347c77a65781ee2ac749d550f2a365dc1", - "sha256:c7a01337407dd89005527623a4a72c5c8e2894d22bead0895306b23c6695698f", - "sha256:c9b929f13677b10f63124c1a410994a401cdd85214ad83ab67cc077fc7e480f0", - "sha256:cdc491ae35a13535fd9196acb5afe1af37c8237df2e54427be3eecda3653127e", - "sha256:e279330bef1744040db8fc432becc8a727b84f456ab62b744d3fdb83f327e121", - "sha256:e29ca27bec8e163dca0c98084040edec3bc49afd10f18b412f483cc68c712744", - "sha256:e7d1797a8a3845437d327145959a2c0c47c05947c9eef5ff1a4c80e499dcc6fa", - "sha256:ea33986b70f83844cd00814cee4451055cd8cab36f00ac64a31f5bb09b31919e", - "sha256:ec74ef02010186185de82cc594058a3ccd8d86821842bbac9873fd4a2cf8be8d", - "sha256:f26b0b547eb8d00e195274cdfc63ce64c8fc2d3e2d00b12bf468ece41a0423a0", - "sha256:f5a27dddefe0e2357d3e617b9079b4bfdc91341a91565111a21ed6ebbc51b22d", - "sha256:f5b76ff64aaac53fede0cc93abf57894ab2a7362986ba22243d06218b93efe46", - "sha256:f9fff78ba10d4250bfc07a01bd6254a6d87dc67f9627adece85c0b2ed754fa96", - "sha256:fa0c739ad8b1996bd24823950e3cb5152ae91fca1c09cc791190bf1627ffefba" + "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43", + "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161", + "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e", + "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76", + "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf", + "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613", + "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600", + "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c", + "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5", + "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1", + "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515", + "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9", + "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c", + "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1", + "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0", + "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054", + "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73", + "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684", + "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d", + "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c", + "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1", + "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e", + "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172", + "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5", + "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2", + "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e", + "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded", + "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a", + "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666", + "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea", + "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63", + "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330", + "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60", + "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079", + "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f", + "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd", + "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c", + "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1", + "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385", + "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e", + "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9", + "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54", + "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad", + "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a", + "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe", + "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1", + "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d", + "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78", + "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0", + "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e", + "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475", + "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c", + "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746", + "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad", + "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9" ], "markers": "python_version >= '3.8'", - "version": "==1.67.1" + "version": "==1.68.1" }, "grpcio-status": { "hashes": [ - "sha256:16e6c085950bdacac97c779e6a502ea671232385e6e37f258884d6883392c2bd", - "sha256:2bf38395e028ceeecfd8866b081f61628114b384da7d51ae064ddc8d766a5d11" + "sha256:66f3d8847f665acfd56221333d66f7ad8927903d87242a482996bdb45e8d28fd", + "sha256:e1378d036c81a1610d7b4c7a146cd663dd13fcc915cf4d7d053929dba5bbb6e1" ], "markers": "python_version >= '3.8'", - "version": "==1.67.1" + "version": "==1.68.1" }, "httplib2": { "hashes": [ @@ -5352,11 +5326,11 @@ }, "identify": { "hashes": [ - "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0", - "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98" + "sha256:285a7d27e397652e8cafe537a6cc97dd470a970f48fb2e9d979aa38eae5513ac", + "sha256:993b0f01b97e0568c179bb9196391ff391bfb88a99099dbf5ce392b68f42d0af" ], - "markers": "python_version >= '3.8'", - "version": "==2.6.1" + "markers": "python_version >= '3.9'", + "version": "==2.6.4" }, "idna": { "hashes": [ @@ -5376,26 +5350,26 @@ }, "jinja2": { "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", + "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" ], "markers": "python_version >= '3.7'", - "version": "==3.1.4" + "version": "==3.1.5" }, "langcodes": { "hashes": [ - "sha256:68f686fc3d358f222674ecf697ddcee3ace3c2fe325083ecad2543fd28a20e77", - "sha256:a24879fed238013ac3af2424b9d1124e38b4a38b2044fd297c8ff38e5912e718" + "sha256:1eef8168d07e51e131a2497ffecad4b663f6208e7c3ae3b8dc15c51734a6f801", + "sha256:853c69d1a35e0e13da2f427bb68fb2fa4a8f4fb899e0c62ad8df8d073dcfed33" ], - "markers": "python_version >= '3.8'", - "version": "==3.4.1" + "markers": "python_version >= '3.9'", + "version": "==3.5.0" }, "language-data": { "hashes": [ - "sha256:77d5cab917f91ee0b2f1aa7018443e911cf8985ef734ca2ba3940770f6a3816b", - "sha256:82a86050bbd677bfde87d97885b17566cfe75dad3ac4f5ce44b52c28f752e773" + "sha256:7600ef8aa39555145d06c89f0c324bf7dab834ea0b0a439d8243762e3ebad7ec", + "sha256:e2ee943551b5ae5f89cd0e801d1fc3835bb0ef5b7e9c3a4e8e17b2b214548fbf" ], - "version": "==1.2.0" + "version": "==1.3.0" }, "marisa-trie": { "hashes": [ @@ -5598,12 +5572,12 @@ }, "mkdocs-material": { "hashes": [ - "sha256:4aae0664c456fd12837a3192e0225c17960ba8bf55d7f0a7daef7e4b0b914a34", - "sha256:83be7ff30b65a1e4930dfa4ab911e75780a3afc9583d162692e434581cb46979" + "sha256:3671bb282b4f53a1c72e08adbe04d2481a98f85fed392530051f80ff94a9621d", + "sha256:c3c2d8176b18198435d3a3e119011922f3e11424074645c24019c2dcf08a360e" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==9.5.43" + "version": "==9.5.49" }, "mkdocs-material-extensions": { "hashes": [ @@ -5615,60 +5589,66 @@ }, "mkdocstrings": { "hashes": [ - "sha256:1248f3228464f3b8d1a15bd91249ce1701fe3104ac517a5f167a0e01ca850ba5", - "sha256:34a8b50f1e6cfd29546c6c09fbe02154adfb0b361bb758834bf56aa284ba876e" + "sha256:16adca6d6b0a1f9e0c07ff0b02ced8e16f228a9d65a37c063ec4c14d7b76a657", + "sha256:6ceaa7ea830770959b55a16203ac63da24badd71325b96af950e59fd37366332" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==0.26.2" + "version": "==0.27.0" }, "mkdocstrings-python": { "hashes": [ - "sha256:7a1760941c0b52a2cd87b960a9e21112ffe52e7df9d0b9583d04d47ed2e186f3", - "sha256:7f7d40d6db3cb1f5d19dbcd80e3efe4d0ba32b073272c0c0de9de2e604eda62a" + "sha256:2dbd5757e8375b9720e81db16f52f1856bf59905428fd7ef88005d1370e2f64c", + "sha256:b88bbb207bab4086434743849f8e796788b373bd32e7bfefbf8560ac45d88f97" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==1.12.2" + "version": "==1.13.0" }, "mypy": { "hashes": [ - "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc", - "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", - "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", - "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74", - "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a", - "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", - "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", - "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", - "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", - "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", - "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d", - "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6", - "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", - "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", - "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", - "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", - "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", - "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc", - "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", - "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb", - "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", - "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732", - "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", - "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", - "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", - "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", - "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", - "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24", - "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", - "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b", - "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", - "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8" + "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c", + "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", + "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", + "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", + "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9", + "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", + "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", + "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35", + "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319", + "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc", + "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb", + "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", + "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", + "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60", + "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31", + "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", + "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", + "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", + "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", + "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", + "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837", + "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6", + "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", + "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", + "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", + "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", + "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", + "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", + "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b", + "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac", + "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", + "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", + "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", + "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", + "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", + "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", + "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", + "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.13.0" + "version": "==1.14.1" }, "mypy-extensions": { "hashes": [ @@ -5688,62 +5668,64 @@ }, "numpy": { "hashes": [ - "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", - "sha256:12edb90831ff481f7ef5f6bc6431a9d74dc0e5ff401559a71e5e4611d4f2d466", - "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", - "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", - "sha256:13602b3174432a35b16c4cfb5de9a12d229727c3dd47a6ce35111f2ebdf66ff4", - "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", - "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", - "sha256:1c193d0b0238638e6fc5f10f1b074a6993cb13b0b431f64079a509d63d3aa8b7", - "sha256:1ebec5fd716c5a5b3d8dfcc439be82a8407b7b24b230d0ad28a81b61c2f4659a", - "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", - "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", - "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", - "sha256:2cbba4b30bf31ddbe97f1c7205ef976909a93a66bb1583e983adbd155ba72ac2", - "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", - "sha256:30d53720b726ec36a7f88dc873f0eec8447fbc93d93a8f079dfac2629598d6ee", - "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", - "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", - "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", - "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", - "sha256:5006b13a06e0b38d561fab5ccc37581f23c9511879be7693bd33c7cd15ca227c", - "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", - "sha256:6cdb606a7478f9ad91c6283e238544451e3a95f30fb5467fbf715964341a8a86", - "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", - "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", - "sha256:7c1c60328bd964b53f8b835df69ae8198659e2b9302ff9ebb7de4e5a5994db3d", - "sha256:860ec6e63e2c5c2ee5e9121808145c7bf86c96cca9ad396c0bd3e0f2798ccbe2", - "sha256:8e00ea6fc82e8a804433d3e9cedaa1051a1422cb6e443011590c14d2dea59146", - "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", - "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", - "sha256:a65acfdb9c6ebb8368490dbafe83c03c7e277b37e6857f0caeadbbc56e12f4fb", - "sha256:a7d80b2e904faa63068ead63107189164ca443b42dd1930299e0d1cb041cec2e", - "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", - "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", - "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", - "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", - "sha256:b42a1a511c81cc78cbc4539675713bbcf9d9c3913386243ceff0e9429ca892fe", - "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", - "sha256:bdd407c40483463898b84490770199d5714dcc9dd9b792f6c6caccc523c00952", - "sha256:c6eef7a2dbd0abfb0d9eaf78b73017dbfd0b54051102ff4e6a7b2980d5ac1a03", - "sha256:c82af4b2ddd2ee72d1fc0c6695048d457e00b3582ccde72d8a1c991b808bb20f", - "sha256:d666cb72687559689e9906197e3bec7b736764df6a2e58ee265e360663e9baf7", - "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", - "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", - "sha256:da65fb46d4cbb75cb417cddf6ba5e7582eb7bb0b47db4b99c9fe5787ce5d91f5", - "sha256:e2b49c3c0804e8ecb05d59af8386ec2f74877f7ca8fd9c1e00be2672e4d399b1", - "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", - "sha256:e8d3ca0a72dd8846eb6f7dfe8f19088060fcb76931ed592d29128e0219652884", - "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", - "sha256:f1eb068ead09f4994dec71c24b2844f1e4e4e013b9629f812f292f04bd1510d9", - "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", - "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", - "sha256:faa88bc527d0f097abdc2c663cddf37c05a1c2f113716601555249805cf573f1", - "sha256:fc44e3c68ff00fd991b59092a54350e6e4911152682b4782f68070985aa9e648" + "sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2", + "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5", + "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60", + "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71", + "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631", + "sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8", + "sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2", + "sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16", + "sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa", + "sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591", + "sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964", + "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821", + "sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484", + "sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957", + "sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800", + "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918", + "sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95", + "sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0", + "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e", + "sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d", + "sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73", + "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59", + "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51", + "sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355", + "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348", + "sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e", + "sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440", + "sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675", + "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84", + "sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046", + "sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab", + "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712", + "sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308", + "sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315", + "sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3", + "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008", + "sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5", + "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2", + "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e", + "sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7", + "sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf", + "sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab", + "sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd", + "sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf", + "sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8", + "sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb", + "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268", + "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d", + "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780", + "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716", + "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e", + "sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528", + "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af", + "sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7", + "sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51" ], "markers": "python_version >= '3.10'", - "version": "==2.1.2" + "version": "==2.2.1" }, "oauthlib": { "hashes": [ @@ -5755,11 +5737,11 @@ }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" }, "paginate": { "hashes": [ @@ -5901,20 +5883,20 @@ }, "protobuf": { "hashes": [ - "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24", - "sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535", - "sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b", - "sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548", - "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584", - "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b", - "sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36", - "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", - "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868", - "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687", - "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed" + "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a", + "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355", + "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9", + "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e", + "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9", + "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb", + "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e", + "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e", + "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851", + "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19", + "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181" ], "markers": "python_version >= '3.8'", - "version": "==5.28.3" + "version": "==5.29.2" }, "pyasn1": { "hashes": [ @@ -5966,11 +5948,11 @@ }, "pymdown-extensions": { "hashes": [ - "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77", - "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7" + "sha256:80bc33d715eec68e683e04298946d47d78c7739e79d808203df278ee8ef89428", + "sha256:e0b351494dc0d8d14a1f52b39b1499a00ef1566b4ba23dc74f1eba75c736f5dd" ], "markers": "python_version >= '3.8'", - "version": "==10.12" + "version": "==10.13" }, "pyparsing": { "hashes": [ @@ -5982,30 +5964,30 @@ }, "pyright": { "hashes": [ - "sha256:577de60224f7fe36505d5b181231e3a395d427b7873be0bbcaa962a29ea93a60", - "sha256:6a1f495a261a72e12ad17e20d1ae3df4511223c773b19407cfa006229b1b08a5" + "sha256:54fa186f8b3e8a55a44ebfa842636635688670c6896dcf6cf4a7fc75062f4d15", + "sha256:66b2d42cdf5c3cbab05f2f4b76e8bec8aa78e679bfa0b6ad7b923d9e027cadb2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.1.387" + "version": "==1.1.391" }, "pytest": { "hashes": [ - "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", - "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2" + "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", + "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.3.3" + "version": "==8.3.4" }, "pytest-asyncio": { "hashes": [ - "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", - "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276" + "sha256:8c0610303c9e0442a5db8604505fc0f545456ba1528824842b37b4a626cbf609", + "sha256:db5432d18eac6b7e28b46dcd9b69921b55c3b1086e85febfe04e70b18d9e81b3" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==0.24.0" + "markers": "python_version >= '3.9'", + "version": "==0.25.0" }, "pytest-cov": { "hashes": [ @@ -6118,103 +6100,103 @@ }, "regex": { "hashes": [ - "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623", - "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199", - "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", - "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", - "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca", - "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066", - "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca", - "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39", - "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d", - "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", - "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35", - "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408", - "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5", - "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", - "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", - "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", - "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", - "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168", - "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca", - "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508", - "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", - "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", - "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b", - "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4", - "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", - "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6", - "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c", - "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62", - "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", - "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", - "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba", - "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", - "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e", - "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", - "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4", - "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", - "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71", - "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", - "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d", - "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", - "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8", - "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", - "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8", - "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", - "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16", - "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664", - "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a", - "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", - "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd", - "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", - "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", - "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", - "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", - "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", - "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", - "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", - "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", - "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", - "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", - "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8", - "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e", - "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", - "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8", - "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", - "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366", - "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137", - "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", - "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", - "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3", - "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771", - "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60", - "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a", - "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", - "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", - "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", - "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", - "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", - "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", - "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142", - "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89", - "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c", - "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", - "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35", - "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a", - "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", - "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9", - "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", - "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", - "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", - "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb", - "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0", - "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", - "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb", - "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919" + "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c", + "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60", + "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d", + "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d", + "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67", + "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773", + "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", + "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef", + "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad", + "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe", + "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", + "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114", + "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", + "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39", + "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e", + "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3", + "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", + "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d", + "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e", + "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", + "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7", + "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f", + "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0", + "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54", + "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b", + "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", + "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd", + "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57", + "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34", + "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", + "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f", + "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b", + "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519", + "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", + "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a", + "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638", + "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b", + "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839", + "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", + "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf", + "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", + "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0", + "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f", + "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95", + "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4", + "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e", + "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13", + "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", + "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2", + "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008", + "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9", + "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc", + "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48", + "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20", + "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89", + "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e", + "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf", + "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b", + "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd", + "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", + "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29", + "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b", + "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3", + "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45", + "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3", + "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983", + "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e", + "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", + "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4", + "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", + "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467", + "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577", + "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001", + "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", + "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55", + "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9", + "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf", + "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6", + "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e", + "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde", + "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62", + "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df", + "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51", + "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5", + "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86", + "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2", + "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2", + "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0", + "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c", + "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f", + "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", + "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2", + "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9", + "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91" ], "markers": "python_version >= '3.8'", - "version": "==2024.9.11" + "version": "==2024.11.6" }, "requests": { "hashes": [ @@ -6242,19 +6224,19 @@ }, "setuptools": { "hashes": [ - "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", - "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686" + "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", + "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d" ], - "markers": "python_version >= '3.8'", - "version": "==75.3.0" + "markers": "python_version >= '3.9'", + "version": "==75.6.0" }, "six": { "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==1.16.0" + "version": "==1.17.0" }, "snowballstemmer": { "hashes": [ @@ -6265,27 +6247,27 @@ }, "sqlparse": { "hashes": [ - "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4", - "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e" + "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", + "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca" ], "markers": "python_version >= '3.8'", - "version": "==0.5.1" + "version": "==0.5.3" }, "types-httplib2": { "hashes": [ - "sha256:1eda99fea18ec8a1dc1a725ead35b889d0836fec1b11ae6f1fe05440724c1d15", - "sha256:8cd706fc81f0da32789a4373a28df6f39e9d5657d1281db4d2fd22ee29e83661" + "sha256:42b67f16a6b0abb337a1fcea628dcd335e1e75f32cd198a657f41a6f4d507508", + "sha256:b15aed53ae5430b87205b6ac270d6332cb5e28e27151e2ac4848fe417827eb54" ], "markers": "python_version >= '3.8'", - "version": "==0.22.0.20240310" + "version": "==0.22.0.20241221" }, "types-pyyaml": { "hashes": [ - "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570", - "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587" + "sha256:7f07622dbd34bb9c8b264fe860a17e0efcad00d50b5f27e93984909d9363498c", + "sha256:fa4d32565219b68e6dee5f67534c722e53c00d1cfc09c435ef04d7353e1e96e6" ], "markers": "python_version >= '3.8'", - "version": "==6.0.12.20240917" + "version": "==6.0.12.20241230" }, "types-requests": { "hashes": [ @@ -6313,19 +6295,19 @@ }, "urllib3": { "hashes": [ - "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", - "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", + "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d" ], - "markers": "python_version >= '3.8'", - "version": "==2.2.3" + "markers": "python_version >= '3.9'", + "version": "==2.3.0" }, "virtualenv": { "hashes": [ - "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba", - "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4" + "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0", + "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa" ], "markers": "python_version >= '3.8'", - "version": "==20.27.1" + "version": "==20.28.0" }, "watchdog": { "hashes": [ @@ -6373,46 +6355,46 @@ }, "zope.interface": { "hashes": [ - "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f", - "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e", - "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616", - "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3", - "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67", - "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8", - "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b", - "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585", - "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446", - "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd", - "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a", - "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3", - "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c", - "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853", - "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f", - "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5", - "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8", - "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501", - "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd", - "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029", - "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e", - "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f", - "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580", - "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c", - "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9", - "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0", - "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2", - "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d", - "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73", - "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16", - "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a", - "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267", - "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b", - "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d", - "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053", - "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25", - "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770" + "sha256:033b3923b63474800b04cba480b70f6e6243a62208071fc148354f3f89cc01b7", + "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a", + "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7", + "sha256:0ef9e2f865721553c6f22a9ff97da0f0216c074bd02b25cf0d3af60ea4d6931d", + "sha256:1090c60116b3da3bfdd0c03406e2f14a1ff53e5771aebe33fec1edc0a350175d", + "sha256:144964649eba4c5e4410bb0ee290d338e78f179cdbfd15813de1a664e7649b3b", + "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d", + "sha256:1909f52a00c8c3dcab6c4fad5d13de2285a4b3c7be063b239b8dc15ddfb73bd2", + "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465", + "sha256:224b7b0314f919e751f2bca17d15aad00ddbb1eadf1cb0190fa8175edb7ede62", + "sha256:25e6a61dcb184453bb00eafa733169ab6d903e46f5c2ace4ad275386f9ab327a", + "sha256:27f926f0dcb058211a3bb3e0e501c69759613b17a553788b2caeb991bed3b61d", + "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5", + "sha256:2ad9913fd858274db8dd867012ebe544ef18d218f6f7d1e3c3e6d98000f14b75", + "sha256:31d06db13a30303c08d61d5fb32154be51dfcbdb8438d2374ae27b4e069aac40", + "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98", + "sha256:3f6771d1647b1fc543d37640b45c06b34832a943c80d1db214a37c31161a93f1", + "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd", + "sha256:52e446f9955195440e787596dccd1411f543743c359eeb26e9b2c02b077b0519", + "sha256:550f1c6588ecc368c9ce13c44a49b8d6b6f3ca7588873c679bd8fd88a1b557b6", + "sha256:72cd1790b48c16db85d51fbbd12d20949d7339ad84fd971427cf00d990c1f137", + "sha256:7bd449c306ba006c65799ea7912adbbfed071089461a19091a228998b82b1fdb", + "sha256:7dc5016e0133c1a1ec212fc87a4f7e7e562054549a99c73c8896fa3a9e80cbc7", + "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c", + "sha256:80ecf2451596f19fd607bb09953f426588fc1e79e93f5968ecf3367550396b22", + "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe", + "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54", + "sha256:a102424e28c6b47c67923a1f337ede4a4c2bba3965b01cf707978a801fc7442c", + "sha256:a19a6cc9c6ce4b1e7e3d319a473cf0ee989cbbe2b39201d7c19e214d2dfb80c7", + "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b", + "sha256:baf95683cde5bc7d0e12d8e7588a3eb754d7c4fa714548adcd96bdf90169f021", + "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d", + "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2", + "sha256:d3a8ffec2a50d8ec470143ea3d15c0c52d73df882eef92de7537e8ce13475e8a", + "sha256:e204937f67b28d2dca73ca936d3039a144a081fc47a07598d44854ea2a106239", + "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398", + "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89" ], "markers": "python_version >= '3.8'", - "version": "==7.1.1" + "version": "==7.2" } } } diff --git a/breathecode/activity/management/commands/upload_activities.py b/breathecode/activity/management/commands/upload_activities.py index db037716f..961de58c4 100644 --- a/breathecode/activity/management/commands/upload_activities.py +++ b/breathecode/activity/management/commands/upload_activities.py @@ -1,10 +1,12 @@ import os + +from django.core.cache import cache from django.core.management.base import BaseCommand from django.utils import timezone -from django.core.cache import cache + from breathecode.activity import tasks -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False def db_backup_bucket(): diff --git a/breathecode/activity/tasks.py b/breathecode/activity/tasks.py index 9349f5378..b38d8e179 100644 --- a/breathecode/activity/tasks.py +++ b/breathecode/activity/tasks.py @@ -8,6 +8,7 @@ from typing import Optional import zstandard +from capyc.core.managers import feature from celery import shared_task from django.core.cache import cache from django.utils import timezone @@ -24,7 +25,6 @@ from breathecode.utils import NDB from breathecode.utils.decorators import TaskPriority from breathecode.utils.redis import Lock -from capyc.core.managers import feature from .models import StudentActivity @@ -38,7 +38,7 @@ def get_activity_sampling_rate(): return 60 -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False API_URL = os.getenv("API_URL", "") diff --git a/breathecode/admissions/management/commands/fix_assets_slug_in_syllabus_json.py b/breathecode/admissions/management/commands/fix_assets_slug_in_syllabus_json.py new file mode 100644 index 000000000..ebecc6ca9 --- /dev/null +++ b/breathecode/admissions/management/commands/fix_assets_slug_in_syllabus_json.py @@ -0,0 +1,58 @@ +import json +from django.core.management.base import BaseCommand +from .models import SyllabusVersion +from breathecode.registry.models import Asset + + +class Command(BaseCommand): + help = "Replace asset aliases in the syllabus with the current slugs" + + def handle(self, *args, **options): + try: + from breathecode.certificate.actions import syllabus_weeks_to_days + + syllabus_list = SyllabusVersion.objects.all() + key_map = { + "QUIZ": "quizzes", + "LESSON": "lessons", + "EXERCISE": "replits", + "PROJECT": "assignments", + } + + for s in syllabus_list: + if isinstance(s.json, str): + s.json = json.loads(s.json) + + # in case the json contains "weeks" instead of "days" + s.json = syllabus_weeks_to_days(s.json) + + for module_index, day in enumerate(s.json["days"]): + + for asset_type in key_map: + if key_map[asset_type] not in day: + continue + + for asset_index, assignment in enumerate(day[key_map[asset_type]]): + assignment_slug = assignment["slug"] if isinstance(assignment, dict) else assignment + asset = Asset.get_by_slug(assignment_slug) + + if asset is not None and (asset.lang not in ["us", "en"] or asset.slug != assignment_slug): + updated_slug = assignment_slug + + if asset.lang not in ["us", "en"]: + english_translation = asset.all_translations.filter(lang__in=["en", "us"]).first() + updated_slug = english_translation.slug + elif asset.slug != assignment_slug: + updated_slug = asset.slug + + if isinstance(assignment, dict): + s.json["days"][module_index][key_map[asset_type]][asset_index][ + "slug" + ] = updated_slug + else: + s.json["days"][module_index][key_map[asset_type]][asset_index] = updated_slug + + s.save() + + except Exception: + self.stderr.write("Failed to fix assets slugs in all syllabus") diff --git a/breathecode/admissions/migrations/0065_cohort_cohorts_order_cohort_micro_cohorts.py b/breathecode/admissions/migrations/0065_cohort_cohorts_order_cohort_micro_cohorts.py new file mode 100644 index 000000000..a9cdc72c6 --- /dev/null +++ b/breathecode/admissions/migrations/0065_cohort_cohorts_order_cohort_micro_cohorts.py @@ -0,0 +1,34 @@ +# Generated by Django 5.1.2 on 2024-11-07 22:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("admissions", "0064_academy_legal_name"), + ] + + operations = [ + migrations.AddField( + model_name="cohort", + name="cohorts_order", + field=models.CharField( + blank=True, + default=None, + help_text="An IDs comma separated list to indicate the order in which the micro cohorts will be displayed", + max_length=50, + null=True, + ), + ), + migrations.AddField( + model_name="cohort", + name="micro_cohorts", + field=models.ManyToManyField( + blank=True, + help_text="This cohorts will represent small courses inside a main course", + related_name="cohorts", + to="admissions.cohort", + ), + ), + ] diff --git a/breathecode/admissions/migrations/0066_cohort_color.py b/breathecode/admissions/migrations/0066_cohort_color.py new file mode 100644 index 000000000..d56cc3691 --- /dev/null +++ b/breathecode/admissions/migrations/0066_cohort_color.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.2 on 2024-11-14 12:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("admissions", "0065_cohort_cohorts_order_cohort_micro_cohorts"), + ] + + operations = [ + migrations.AddField( + model_name="cohort", + name="color", + field=models.CharField( + blank=True, + default=None, + help_text="Add the color with hexadecimal format, i.e.: #FFFFFF", + max_length=50, + null=True, + ), + ), + ] diff --git a/breathecode/admissions/migrations/0067_alter_cohort_micro_cohorts.py b/breathecode/admissions/migrations/0067_alter_cohort_micro_cohorts.py new file mode 100644 index 000000000..73f8ebb8a --- /dev/null +++ b/breathecode/admissions/migrations/0067_alter_cohort_micro_cohorts.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.2 on 2024-11-15 09:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("admissions", "0066_cohort_color"), + ] + + operations = [ + migrations.AlterField( + model_name="cohort", + name="micro_cohorts", + field=models.ManyToManyField( + blank=True, + help_text="This cohorts will represent small courses inside a main course", + related_name="main_cohorts", + to="admissions.cohort", + ), + ), + ] diff --git a/breathecode/admissions/migrations/0068_merge_20241216_1552.py b/breathecode/admissions/migrations/0068_merge_20241216_1552.py new file mode 100644 index 000000000..f7779d555 --- /dev/null +++ b/breathecode/admissions/migrations/0068_merge_20241216_1552.py @@ -0,0 +1,13 @@ +# Generated by Django 5.1.3 on 2024-12-16 15:52 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("admissions", "0065_alter_cohortuser_educational_status"), + ("admissions", "0067_alter_cohort_micro_cohorts"), + ] + + operations = [] diff --git a/breathecode/admissions/models.py b/breathecode/admissions/models.py index 1e5cf7ad6..09e4bf1ec 100644 --- a/breathecode/admissions/models.py +++ b/breathecode/admissions/models.py @@ -362,6 +362,28 @@ class Cohort(models.Model): language = models.CharField(max_length=2, default="en", db_index=True) + micro_cohorts = models.ManyToManyField( + "Cohort", + blank=True, + help_text="This cohorts will represent small courses inside a main course", + related_name="main_cohorts", + ) + + cohorts_order = models.CharField( + max_length=50, + null=True, + blank=True, + default=None, + help_text="An IDs comma separated list to indicate the order in which the micro cohorts will be displayed", + ) + color = models.CharField( + max_length=50, + null=True, + blank=True, + default=None, + help_text="Add the color with hexadecimal format, i.e.: #FFFFFF", + ) + created_at = models.DateTimeField(auto_now_add=True, editable=False) updated_at = models.DateTimeField(auto_now=True, editable=False) diff --git a/breathecode/admissions/receivers.py b/breathecode/admissions/receivers.py index 226f02b09..c8de81886 100644 --- a/breathecode/admissions/receivers.py +++ b/breathecode/admissions/receivers.py @@ -2,6 +2,7 @@ import logging import re from typing import Any, Type +from asgiref.sync import sync_to_async from django.dispatch import receiver @@ -12,7 +13,7 @@ from ..activity import tasks as activity_tasks from .models import Cohort, CohortUser -from .signals import cohort_log_saved, cohort_user_created +from .signals import cohort_log_saved, cohort_user_created, student_edu_status_updated # add your receives here logger = logging.getLogger(__name__) @@ -27,9 +28,25 @@ def process_cohort_history_log(sender: Type[Cohort], instance: Cohort, **kwargs: activity_tasks.get_attendancy_log.delay(instance.id) -@receiver(cohort_user_created, sender=Cohort) -async def new_cohort_user(sender: Type[Cohort], instance: Cohort, **kwargs: Any): - logger.info("Processing Cohort history log for cohort: " + str(instance.id)) +@sync_to_async +def join_to_micro_cohorts(cohort_user): + + micro_cohorts = cohort_user.cohort.micro_cohorts.all() + + user = cohort_user.user + for cohort in micro_cohorts: + micro_cohort_user = CohortUser.objects.filter(user=user, cohort=cohort, role=cohort_user.role).first() + if micro_cohort_user is None: + micro_cohort_user = CohortUser( + user=user, cohort=cohort, role=cohort_user.role, finantial_status="FULLY_PAID" + ) + micro_cohort_user.save() + + +@receiver(cohort_user_created, sender=CohortUser) +async def new_cohort_user(sender: Type[CohortUser], instance: CohortUser, **kwargs: Any): + logger.info("Signal for created cohort user: " + str(instance.id)) + await join_to_micro_cohorts(instance) await authenticate_actions.send_webhook( "rigobot", @@ -76,6 +93,31 @@ def schedule_repository_deletion(sender: Type[Task], instance: Task, **kwargs: A order.save() +@receiver(student_edu_status_updated, sender=CohortUser) +def post_save_cohort_user(sender: Type[CohortUser], instance: CohortUser, **kwargs: Any): + logger.info("Validating if the student is graduating from a saas cohort") + cohort = instance.cohort + + if instance.cohort is None: + return + + if cohort.available_as_saas and instance.educational_status == "GRADUATED": + # main_cohorts is the backwards relationship for the many to many + # it contains every cohort that another cohort is linked to as a micro cohort + main_cohorts = cohort.main_cohorts.all() + for main in main_cohorts: + main_cohort_user = CohortUser.objects.filter(cohort=main, user=instance.user).first() + if main_cohort_user.educational_status != "GRADUATED": + main_cohort = main_cohort_user.cohort + micro_cohorts = main_cohort.micro_cohorts.all() + cohort_users = CohortUser.objects.filter(user=instance.user, cohort__in=micro_cohorts).exclude( + educational_status__in=["GRADUATED"] + ) + if len(cohort_users) == 0: + main_cohort_user.educational_status = "GRADUATED" + main_cohort_user.save() + + @receiver(revision_status_updated, sender=Task, weak=False) def mark_saas_student_as_graduated(sender: Type[Task], instance: Task, **kwargs: Any): logger.info("Processing available as saas student's tasks and marking as GRADUATED if it is") diff --git a/breathecode/admissions/serializers.py b/breathecode/admissions/serializers.py index e322a2b64..af21b8f83 100644 --- a/breathecode/admissions/serializers.py +++ b/breathecode/admissions/serializers.py @@ -27,6 +27,15 @@ logger = logging.getLogger(__name__) +class GetTinyCohortSerializer(serpy.Serializer): + """The serializer schema definition.""" + + # Use a Field subclass like IntField if you need more validation. + id = serpy.Field() + name = serpy.Field() + slug = serpy.Field() + + class CountrySerializer(serpy.Serializer): """The serializer schema definition.""" @@ -361,6 +370,7 @@ class PublicCohortSerializer(serpy.Serializer): name = serpy.Field() never_ends = serpy.Field() private = serpy.Field() + micro_cohorts = serpy.MethodField() language = serpy.Field() kickoff_date = serpy.Field() ending_date = serpy.Field() @@ -378,6 +388,10 @@ def get_distance(self, obj): return haversine(obj.longitude, obj.latitude, obj.academy.longitude, obj.academy.latitude) + def get_micro_cohorts(self, obj): + cohorts = obj.micro_cohorts.all() + return GetTinyCohortSerializer(cohorts, many=True).data + class GetSmallCohortSerializer(serpy.Serializer): """The serializer schema definition.""" @@ -433,8 +447,11 @@ class GetMeCohortSerializer(serpy.Serializer): name = serpy.Field() kickoff_date = serpy.Field() ending_date = serpy.Field() + micro_cohorts = serpy.MethodField() + cohorts_order = serpy.Field() intro_video = serpy.Field() current_day = serpy.Field() + color = serpy.Field() current_module = serpy.Field() syllabus_version = SyllabusVersionSmallSerializer(required=False) academy = GetAcademySerializer() @@ -442,6 +459,10 @@ class GetMeCohortSerializer(serpy.Serializer): is_hidden_on_prework = serpy.Field() available_as_saas = serpy.Field() + def get_micro_cohorts(self, obj): + cohorts = obj.micro_cohorts.all() + return GetTinyCohortSerializer(cohorts, many=True).data + class GetPublicCohortUserSerializer(serpy.Serializer): user = UserPublicSerializer() diff --git a/breathecode/admissions/tests/permissions/contexts/tests_academy.py b/breathecode/admissions/tests/permissions/contexts/tests_academy.py deleted file mode 100644 index 5863fdb1c..000000000 --- a/breathecode/admissions/tests/permissions/contexts/tests_academy.py +++ /dev/null @@ -1,49 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from ....permissions.contexts import academy -from ...mixins import AdmissionsTestCase - -from breathecode.services import LaunchDarkly - - -def serializer(academy): - return { - "id": academy.id, - "slug": academy.slug, - "city": academy.city.name, - "country": academy.country.name, - "zip_code": academy.zip_code, - "timezone": academy.timezone, - } - - -value = random.randint(1, 1000) - - -class AcademyEventTestSuite(AdmissionsTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.context", MagicMock(return_value=value)) - def test_make_right_calls(self): - model = self.bc.database.create(academy=1) - - ld = LaunchDarkly() - result = academy(ld, model.academy) - - self.assertEqual( - self.bc.database.list_of("admissions.Academy"), - [ - self.bc.format.to_dict(model.academy), - ], - ) - - contexts = serializer(model.academy) - - self.assertEqual( - LaunchDarkly.context.call_args_list, - [ - call("1", f"{model.academy.name} ({model.academy.slug})", "academy", contexts), - ], - ) - - self.assertEqual(result, value) diff --git a/breathecode/admissions/tests/receivers/tests_new_cohort_user.py b/breathecode/admissions/tests/receivers/tests_new_cohort_user.py new file mode 100644 index 000000000..d3a68c646 --- /dev/null +++ b/breathecode/admissions/tests/receivers/tests_new_cohort_user.py @@ -0,0 +1,109 @@ +import random + +import pytest + +from breathecode.tests.mixins.breathecode_mixin.breathecode import Breathecode + + +@pytest.fixture(autouse=True) +def arange(db, bc: Breathecode, fake): + + yield + + +def test_with_one_micro_cohort(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohort = bc.database.create( + cohort={"available_as_saas": True}, + ) + + model_main_cohort = bc.database.create( + user=1, + cohort_user={"role": "STUDENT"}, + cohort={"available_as_saas": True, "micro_cohorts": [model_micro_cohort.cohort]}, + ) + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_main_cohort.cohort_user), + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "id": 2, + "cohort_id": 1, + "finantial_status": "FULLY_PAID", + }, + ] + + +def test_with_many_micro_cohorts(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohort = bc.database.create( + cohort=[{"available_as_saas": True}, {"available_as_saas": True}], + ) + + model_main_cohort = bc.database.create( + user=1, + cohort_user={"role": "STUDENT"}, + cohort={ + "available_as_saas": True, + "micro_cohorts": [model_micro_cohort.cohort[0], model_micro_cohort.cohort[1]], + }, + ) + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_main_cohort.cohort_user), + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "id": 2, + "cohort_id": 1, + "finantial_status": "FULLY_PAID", + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "id": 3, + "cohort_id": 2, + "finantial_status": "FULLY_PAID", + }, + ] + + +def test_with_cohort_users_previously_created(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohorts = bc.database.create( + cohort=[{"available_as_saas": True}, {"available_as_saas": True}], + ) + + model_cohort_users = bc.database.create( + user=1, + cohort_user=[ + {"role": "STUDENT", "cohort": model_micro_cohorts.cohort[0]}, + {"role": "STUDENT", "cohort": model_micro_cohorts.cohort[1]}, + ], + ) + + model_main_cohort = bc.database.create( + cohort_user={"user": model_cohort_users.user, "role": "STUDENT"}, + cohort={"available_as_saas": True, "micro_cohorts": [*model_micro_cohorts.cohort]}, + ) + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "id": 1, + "cohort_id": 1, + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "id": 2, + "cohort_id": 2, + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + }, + ] diff --git a/breathecode/admissions/tests/receivers/tests_post_save_cohort_user.py b/breathecode/admissions/tests/receivers/tests_post_save_cohort_user.py new file mode 100644 index 000000000..9b3cc9a7c --- /dev/null +++ b/breathecode/admissions/tests/receivers/tests_post_save_cohort_user.py @@ -0,0 +1,154 @@ +import random + +import pytest + +from breathecode.tests.mixins.breathecode_mixin.breathecode import Breathecode + + +@pytest.fixture(autouse=True) +def arange(db, bc: Breathecode, fake): + + def wrapper(task=1, cohort_user=1, syllabus_version={}, cohort=1): + return bc.database.create( + task=task, + cohort_user=cohort_user, + cohort=cohort, + ) + + yield wrapper + + +def test_no_graduated_status(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohort = bc.database.create( + user=1, + cohort_user={"role": "STUDENT"}, + cohort={"available_as_saas": True}, + ) + + model_main_cohort = bc.database.create( + cohort_user={"user": model_micro_cohort.user, "role": "STUDENT"}, + cohort={"available_as_saas": True, "micro_cohorts": [model_micro_cohort.cohort]}, + ) + + model_micro_cohort.cohort_user.educational_status = "POSTPONED" + model_micro_cohort.cohort_user.save() + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_micro_cohort.cohort_user), + "educational_status": "POSTPONED", + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + }, + ] + + +def test_with_one_micro_cohort(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohort = bc.database.create( + user=1, + cohort_user={"role": "STUDENT"}, + cohort={"available_as_saas": True}, + ) + + model_main_cohort = bc.database.create( + cohort_user={"user": model_micro_cohort.user, "role": "STUDENT"}, + cohort={"available_as_saas": True, "micro_cohorts": [model_micro_cohort.cohort]}, + ) + + model_micro_cohort.cohort_user.educational_status = "GRADUATED" + model_micro_cohort.cohort_user.save() + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_micro_cohort.cohort_user), + "educational_status": "GRADUATED", + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "educational_status": "GRADUATED", + }, + ] + + +def test_with_many_micro_cohorts_one_graduated(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohorts = bc.database.create( + cohort=[{"available_as_saas": True}, {"available_as_saas": True}], + ) + + model_cohort_users = bc.database.create( + user=1, + cohort_user=[ + {"role": "STUDENT", "cohort": model_micro_cohorts.cohort[0]}, + {"role": "STUDENT", "cohort": model_micro_cohorts.cohort[1]}, + ], + ) + + model_main_cohort = bc.database.create( + cohort_user={"user": model_cohort_users.user, "role": "STUDENT"}, + cohort={"available_as_saas": True, "micro_cohorts": [*model_micro_cohorts.cohort]}, + ) + + model_cohort_users.cohort_user[0].educational_status = "GRADUATED" + model_cohort_users.cohort_user[0].save() + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_cohort_users.cohort_user[0]), + "educational_status": "GRADUATED", + }, + { + **bc.format.to_dict(model_cohort_users.cohort_user[1]), + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + }, + ] + + +def test_with_many_micro_cohorts_many_graduated(enable_signals, bc: Breathecode): + enable_signals() + + model_micro_cohorts = bc.database.create( + cohort=[{"available_as_saas": True}, {"available_as_saas": True}], + ) + + model_cohort_users = bc.database.create( + user=1, + cohort_user=[ + {"role": "STUDENT", "cohort": model_micro_cohorts.cohort[0]}, + {"role": "STUDENT", "cohort": model_micro_cohorts.cohort[1]}, + ], + ) + + model_main_cohort = bc.database.create( + cohort_user={"user": model_cohort_users.user, "role": "STUDENT"}, + cohort={"available_as_saas": True, "micro_cohorts": [*model_micro_cohorts.cohort]}, + ) + + model_cohort_users.cohort_user[0].educational_status = "GRADUATED" + model_cohort_users.cohort_user[0].save() + + model_cohort_users.cohort_user[1].educational_status = "GRADUATED" + model_cohort_users.cohort_user[1].save() + + assert bc.database.list_of("admissions.CohortUser") == [ + { + **bc.format.to_dict(model_cohort_users.cohort_user[0]), + "educational_status": "GRADUATED", + }, + { + **bc.format.to_dict(model_cohort_users.cohort_user[1]), + "educational_status": "GRADUATED", + }, + { + **bc.format.to_dict(model_main_cohort.cohort_user), + "educational_status": "GRADUATED", + }, + ] diff --git a/breathecode/admissions/tests/receivers/tests_schedule_repository_deletion.py b/breathecode/admissions/tests/receivers/tests_schedule_repository_deletion.py index 479fa4740..4e16c7657 100644 --- a/breathecode/admissions/tests/receivers/tests_schedule_repository_deletion.py +++ b/breathecode/admissions/tests/receivers/tests_schedule_repository_deletion.py @@ -1,5 +1,3 @@ -import random - import capyc.pytest as capy import pytest @@ -42,9 +40,9 @@ def test_nothing_happens( @pytest.mark.parametrize( "github_url, username, repo", [ - ("https://github.com/user1/repo1", "user1", "repo1"), - ("https://github.com/user2/repo2", "user2", "repo2"), - ("https://github.com/user3/repo3", "user3", "repo3"), + ("https://github.com/breatheco-de/repo1", "breatheco-de", "repo1"), + ("https://github.com/4GeeksAcademy/repo2", "4GeeksAcademy", "repo2"), + ("https://github.com/4geeksacademy/repo3", "4geeksacademy", "repo3"), ], ) def test_schedule_repository_deletion( @@ -77,5 +75,6 @@ def test_schedule_repository_deletion( "status": "PENDING", "status_text": None, "starts_transferring_at": None, + "notified_at": None, }, ] diff --git a/breathecode/admissions/tests/urls/tests_academy_cohort.py b/breathecode/admissions/tests/urls/tests_academy_cohort.py index 9e9e928f0..660097aeb 100644 --- a/breathecode/admissions/tests/urls/tests_academy_cohort.py +++ b/breathecode/admissions/tests/urls/tests_academy_cohort.py @@ -77,6 +77,7 @@ def cohort_field(data={}): "timezone": "America/Caracas", "is_hidden_on_prework": True, "available_as_saas": False, + "color": None, **data, } @@ -901,6 +902,7 @@ def test_academy_cohort__post__passing_all_statuses__uppercase(self): "accepts_enrollment_suggestions": True, "kickoff_date": UTC_NOW, "available_as_saas": False, + "cohorts_order": None, } ), ], @@ -1002,6 +1004,7 @@ def test_academy_cohort__post__passing_all_statuses__lowercase(self): "accepts_enrollment_suggestions": True, "kickoff_date": UTC_NOW, "available_as_saas": False, + "cohorts_order": None, } ), ], @@ -1103,6 +1106,7 @@ def test_academy_cohort__post__passing_available_as_saas_with__true(self): "accepts_enrollment_suggestions": True, "kickoff_date": UTC_NOW, "available_as_saas": True, + "cohorts_order": None, } ), ], @@ -1204,6 +1208,7 @@ def test_academy_cohort__post__passing_available_as_saas_with__false(self): "accepts_enrollment_suggestions": True, "kickoff_date": UTC_NOW, "available_as_saas": False, + "cohorts_order": None, } ), ], @@ -1304,6 +1309,7 @@ def test_academy_cohort__post__not_passing_available_as_saas(self): "accepts_enrollment_suggestions": True, "kickoff_date": UTC_NOW, "available_as_saas": model.academy.available_as_saas, + "cohorts_order": None, } ), ], diff --git a/breathecode/admissions/tests/urls/tests_academy_cohort_id.py b/breathecode/admissions/tests/urls/tests_academy_cohort_id.py index 0181e2461..2eb385b55 100644 --- a/breathecode/admissions/tests/urls/tests_academy_cohort_id.py +++ b/breathecode/admissions/tests/urls/tests_academy_cohort_id.py @@ -676,6 +676,7 @@ def test_cohort_id__put__with_id__with_data_in_body(self): "accepts_enrollment_suggestions": True, "current_day": data["current_day"], "current_module": None, + "cohorts_order": None, "ending_date": model["cohort"].ending_date, "id": model["cohort"].id, "kickoff_date": model["cohort"].kickoff_date, @@ -693,6 +694,7 @@ def test_cohort_id__put__with_id__with_data_in_body(self): "timezone": None, "is_hidden_on_prework": True, "available_as_saas": model["cohort"].available_as_saas, + "color": None, } ], ) @@ -849,6 +851,7 @@ def test_cohort_id__put__with_id__with_data_in_body__cohort_with_timezone(self): "accepts_enrollment_suggestions": True, "current_day": data["current_day"], "current_module": None, + "cohorts_order": None, "ending_date": model["cohort"].ending_date, "id": model["cohort"].id, "kickoff_date": model["cohort"].kickoff_date, @@ -866,6 +869,7 @@ def test_cohort_id__put__with_id__with_data_in_body__cohort_with_timezone(self): "timezone": "Europe/Monaco", "is_hidden_on_prework": model["cohort"].is_hidden_on_prework, "available_as_saas": model["cohort"].available_as_saas, + "color": None, } ], ) @@ -1028,6 +1032,7 @@ def test_cohort_id__put__with_id__schedule_related_to_syllabus_of_other_academy_ "accepts_enrollment_suggestions": True, "current_day": data["current_day"], "current_module": None, + "cohorts_order": None, "ending_date": model["cohort"].ending_date, "id": model["cohort"].id, "kickoff_date": model["cohort"].kickoff_date, @@ -1045,6 +1050,7 @@ def test_cohort_id__put__with_id__schedule_related_to_syllabus_of_other_academy_ "timezone": None, "is_hidden_on_prework": model["cohort"].is_hidden_on_prework, "available_as_saas": model["cohort"].available_as_saas, + "color": None, } ], ) @@ -1194,6 +1200,7 @@ def test_cohort_id__put__with_id__schedule_related_to_syllabus_of_other_academy_ "accepts_enrollment_suggestions": True, "current_day": data["current_day"], "current_module": None, + "cohorts_order": None, "ending_date": model["cohort"].ending_date, "id": model["cohort"].id, "kickoff_date": model["cohort"].kickoff_date, @@ -1211,6 +1218,7 @@ def test_cohort_id__put__with_id__schedule_related_to_syllabus_of_other_academy_ "timezone": None, "is_hidden_on_prework": model["cohort"].is_hidden_on_prework, "available_as_saas": model["cohort"].available_as_saas, + "color": None, } ], ) diff --git a/breathecode/admissions/tests/urls/tests_cohort_all.py b/breathecode/admissions/tests/urls/tests_cohort_all.py index f99396f7c..ab1124ead 100644 --- a/breathecode/admissions/tests/urls/tests_cohort_all.py +++ b/breathecode/admissions/tests/urls/tests_cohort_all.py @@ -25,6 +25,7 @@ def get_serializer(cohort, syllabus, syllabus_version, data={}): re.sub(r"\+00:00$", "Z", cohort.kickoff_date.isoformat()) if cohort.kickoff_date else cohort.kickoff_date ), "ending_date": cohort.ending_date, + "micro_cohorts": [], "language": cohort.language.lower(), "remote_available": cohort.remote_available, "syllabus_version": { diff --git a/breathecode/assignments/management/commands/correct_tasks_alias_slug.py b/breathecode/assignments/management/commands/correct_tasks_alias_slug.py new file mode 100644 index 000000000..5a21d5657 --- /dev/null +++ b/breathecode/assignments/management/commands/correct_tasks_alias_slug.py @@ -0,0 +1,25 @@ +from django.core.management.base import BaseCommand +from breathecode.registry.models import Asset +from ...models import Task + + +class Command(BaseCommand): + help = "Replace asset aliases with the current slugs" + + def handle(self, *args, **options): + + tasks = Task.objects.all() + for task in tasks: + associated_slug = task.associated_slug + asset = Asset.get_by_slug(associated_slug) + if asset is not None: + if asset.lang not in ["us", "en"]: + english_translation = asset.all_translations.filter(lang__in=["en", "us"]).first() + english_slug = english_translation.slug + task.associated_slug = english_slug + task.save() + + # if the slug si different than the stored associated_slug it means that it is an alias + elif asset.slug != associated_slug: + task.associated_slug = asset.slug + task.save() diff --git a/breathecode/assignments/serializers.py b/breathecode/assignments/serializers.py index 861a0e915..8ef149826 100644 --- a/breathecode/assignments/serializers.py +++ b/breathecode/assignments/serializers.py @@ -62,6 +62,7 @@ class TaskGETSerializer(serpy.Serializer): user = UserSmallSerializer() opened_at = serpy.Field() delivered_at = serpy.Field() + cohort = CohortSmallSerializer(required=False) assignment_telemetry = serpy.MethodField() created_at = serpy.Field() diff --git a/breathecode/assignments/tests/urls/tests_task.py b/breathecode/assignments/tests/urls/tests_task.py index 9c9c84a6a..d4e7fb41c 100644 --- a/breathecode/assignments/tests/urls/tests_task.py +++ b/breathecode/assignments/tests/urls/tests_task.py @@ -31,6 +31,7 @@ def get_serializer(self, task, user): "opened_at": self.bc.datetime.to_iso_string(task.opened_at) if task.opened_at else task.opened_at, "delivered_at": self.bc.datetime.to_iso_string(task.delivered_at) if task.delivered_at else task.delivered_at, "user": {"first_name": user.first_name, "id": user.id, "last_name": user.last_name}, + "cohort": {"id": task.cohort.id, "name": task.cohort.name, "slug": task.cohort.slug}, } diff --git a/breathecode/assignments/tests/urls/tests_task_id.py b/breathecode/assignments/tests/urls/tests_task_id.py index 23e066f87..78f48c32a 100644 --- a/breathecode/assignments/tests/urls/tests_task_id.py +++ b/breathecode/assignments/tests/urls/tests_task_id.py @@ -30,6 +30,7 @@ def get_serializer(self, task, user): "opened_at": self.bc.datetime.to_iso_string(task.opened_at) if task.opened_at else task.opened_at, "delivered_at": self.bc.datetime.to_iso_string(task.delivered_at) if task.delivered_at else task.delivered_at, "user": {"first_name": user.first_name, "id": user.id, "last_name": user.last_name}, + "cohort": {"id": task.cohort.id, "name": task.cohort.name, "slug": task.cohort.slug}, } diff --git a/breathecode/assignments/tests/urls/tests_user_me_task.py b/breathecode/assignments/tests/urls/tests_user_me_task.py index 193c2836e..4d752f914 100644 --- a/breathecode/assignments/tests/urls/tests_user_me_task.py +++ b/breathecode/assignments/tests/urls/tests_user_me_task.py @@ -81,6 +81,7 @@ def get_serializer(self, task, user): "opened_at": self.bc.datetime.to_iso_string(task.opened_at) if task.opened_at else task.opened_at, "delivered_at": self.bc.datetime.to_iso_string(task.delivered_at) if task.delivered_at else task.delivered_at, "user": {"first_name": user.first_name, "id": user.id, "last_name": user.last_name}, + "cohort": {"id": task.cohort.id, "name": task.cohort.name, "slug": task.cohort.slug}, } diff --git a/breathecode/authenticate/migrations/0062_delete_app.py b/breathecode/authenticate/migrations/0062_delete_app.py new file mode 100644 index 000000000..5b4a8aecc --- /dev/null +++ b/breathecode/authenticate/migrations/0062_delete_app.py @@ -0,0 +1,16 @@ +# Generated by Django 5.1.4 on 2024-12-28 22:39 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("authenticate", "0061_googlewebhook_type"), + ] + + operations = [ + migrations.DeleteModel( + name="App", + ), + ] diff --git a/breathecode/authenticate/migrations/0063_app.py b/breathecode/authenticate/migrations/0063_app.py new file mode 100644 index 000000000..a71c166b7 --- /dev/null +++ b/breathecode/authenticate/migrations/0063_app.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.4 on 2025-01-07 20:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authenticate", "0062_delete_app"), + ] + + operations = [ + migrations.CreateModel( + name="App", + fields=[ + ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ( + "name", + models.CharField(help_text="Descriptive and unique name of the app", max_length=25, unique=True), + ), + ], + ), + ] diff --git a/breathecode/authenticate/models.py b/breathecode/authenticate/models.py index 418ad9e9f..e86afa9b3 100644 --- a/breathecode/authenticate/models.py +++ b/breathecode/authenticate/models.py @@ -281,9 +281,7 @@ def __init__(self, *args, **kwargs): regex=r"^\+?1?\d{9,15}$", message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", ) - phone = models.CharField( - validators=[phone_regex], max_length=17, blank=True, default="" - ) # validators should be a list + phone = models.CharField(validators=[phone_regex], max_length=17, blank=True, default="") status = models.CharField(max_length=15, choices=PROFILE_ACADEMY_STATUS, default=INVITED, db_index=True) @@ -635,6 +633,11 @@ def get_or_create(cls, user, token_type: str, **kwargs: Unpack[TokenGetOrCreateA return token, created + @classmethod + @sync_to_async + def aget_or_create(cls, user, token_type: str, **kwargs: Unpack[TokenGetOrCreateArgs]) -> Tuple["Token", bool]: + return cls.get_or_create(user=user, token_type=token_type, **kwargs) + @classmethod def get_valid(cls, token: str, async_mode: bool = False, **kwargs: Unpack[TokenFilterArgs]) -> "Token | None": utc_now = timezone.now() diff --git a/breathecode/authenticate/serializers.py b/breathecode/authenticate/serializers.py index 18237b545..f5c5cc871 100644 --- a/breathecode/authenticate/serializers.py +++ b/breathecode/authenticate/serializers.py @@ -4,6 +4,7 @@ import random import urllib.parse +import capyc.django.serializer as capy from capyc.core.i18n import translation from capyc.rest_framework.exceptions import ValidationException from django.contrib.auth.models import Permission, User @@ -14,7 +15,7 @@ from task_manager.django.actions import schedule_task import breathecode.notify.actions as notify_actions -from breathecode.admissions.models import Academy, Cohort, CohortUser +from breathecode.admissions.models import Academy, City, Cohort, CohortUser, Country from breathecode.authenticate.actions import get_app_url, get_user_settings from breathecode.authenticate.tasks import verify_user_invite_email from breathecode.events.models import Event @@ -37,6 +38,98 @@ logger = logging.getLogger(__name__) +class CapyAppUserSerializer(capy.Serializer): + model = User + path = "/v1/auth/app/user" + fields = { + "default": ( + "id", + "username", + "first_name", + "last_name", + "email", + ), + "timestamps": ( + "date_joined", + "last_login", + ), + } + filters = ( + "id", + "username", + "first_name", + "last_name", + "email", + "date_joined", + "last_login", + ) + + +class CapyAppCountrySerializer(capy.Serializer): + model = Country + path = "/v1/auth/app/country" + fields = { + "default": ("code", "name"), + } + filters = ( + "code", + "name", + ) + + +class CapyAppCitySerializer(capy.Serializer): + model = City + path = "/v1/auth/app/city" + fields = {"default": ("id", "name", "country"), "country": ("country[]",)} + filters = ("name",) + country = CapyAppCountrySerializer() + + +class CapyAppAcademySerializer(capy.Serializer): + model = Academy + path = "/v1/auth/app/academy" + fields = { + "default": ("id", "name", "slug", "legal_name", "status"), + "meta": ("white_labeled", "available_as_saas", "is_hidden_on_prework", "timezone"), + "marketing": ("active_campaign_slug", "logistical_information"), + "urls": ("logo_url", "icon_url", "website_url", "white_label_url"), + "emails": ("marketing_email", "feedback_email"), + "social": ("linkedin_url", "youtube_url"), + "location": ("city[]", "country[]", "latitude", "longitude", "zip_code", "street_address"), + "timestamps": ("created_at", "updated_at"), + } + filters = ("name", "slug", "legal_name", "status", "created_at", "available_as_saas") + country = CapyAppCountrySerializer() + city = CapyAppCitySerializer() + + +class CapyAppProfileAcademySerializer(capy.Serializer): + model = ProfileAcademy + path = "/v1/auth/app/student" + fields = { + "default": ( + "id", + "first_name", + "last_name", + "status", + "email", + "phone", + "user", + "academy", + ), + "address": ("address",), + "academy": ("academy[]",), + "user": ("user[]",), + "timestamps": ( + "created_at", + "updated_at", + ), + } + filters = ("status", "email", "id") + academy = CapyAppAcademySerializer() + user = CapyAppUserSerializer() + + class GetSmallCohortSerializer(serpy.Serializer): """The serializer schema definition.""" @@ -862,9 +955,23 @@ class StudentPOSTSerializer(serializers.ModelSerializer): user = serializers.IntegerField(write_only=True, required=False) status = serializers.CharField(read_only=True) + id = serializers.IntegerField(read_only=True) + class Meta: model = ProfileAcademy - fields = ("email", "user", "first_name", "last_name", "address", "phone", "invite", "cohort", "status", "plans") + fields = ( + "email", + "user", + "first_name", + "last_name", + "address", + "phone", + "invite", + "cohort", + "status", + "plans", + "id", + ) list_serializer_class = StudentPOSTListSerializer def validate(self, data): diff --git a/breathecode/authenticate/tests/permissions/contexts/tests_user.py b/breathecode/authenticate/tests/permissions/contexts/tests_user.py deleted file mode 100644 index c16479ef1..000000000 --- a/breathecode/authenticate/tests/permissions/contexts/tests_user.py +++ /dev/null @@ -1,50 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from ....permissions.contexts import user -from ...mixins.new_auth_test_case import AuthTestCase - -from breathecode.services import LaunchDarkly - - -def serializer(user): - return { - "id": user.id, - "email": user.email, - "username": user.username, - "date_joined": user.date_joined, - "groups": [x.name for x in user.groups.all()], - } - - -value = random.randint(1, 1000) - - -class AcademyEventTestSuite(AuthTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.context", MagicMock(return_value=value)) - def test_make_right_calls(self): - model = self.bc.database.create(user=1) - - ld = LaunchDarkly() - result = user(ld, model.user) - - self.assertEqual( - self.bc.database.list_of("auth.User"), - [ - self.bc.format.to_dict(model.user), - ], - ) - - contexts = serializer(model.user) - - print(LaunchDarkly.context.call_args_list) - - self.assertEqual( - LaunchDarkly.context.call_args_list, - [ - call("1", f"{model.user.first_name} {model.user.last_name} ({model.user.email})", "user", contexts), - ], - ) - - self.assertEqual(result, value) diff --git a/breathecode/admissions/tests/permissions/__init__.py b/breathecode/authenticate/tests/serializers/__init__.py similarity index 100% rename from breathecode/admissions/tests/permissions/__init__.py rename to breathecode/authenticate/tests/serializers/__init__.py diff --git a/breathecode/authenticate/tests/serializers/tests_capy_app_academy_serializer.py b/breathecode/authenticate/tests/serializers/tests_capy_app_academy_serializer.py new file mode 100644 index 000000000..61ef72c8f --- /dev/null +++ b/breathecode/authenticate/tests/serializers/tests_capy_app_academy_serializer.py @@ -0,0 +1,58 @@ +import capyc.django.serializer as capy + +from breathecode.authenticate.models import Academy +from breathecode.authenticate.serializers import CapyAppAcademySerializer + + +def test_is_capy_serializer(): + serializer = CapyAppAcademySerializer() + assert isinstance(serializer, capy.Serializer) + + +def test_fields(): + assert CapyAppAcademySerializer.fields == { + "default": ("id", "name", "slug", "legal_name", "status"), + "meta": ("white_labeled", "available_as_saas", "is_hidden_on_prework", "timezone"), + "marketing": ("active_campaign_slug", "logistical_information"), + "urls": ("logo_url", "icon_url", "website_url", "white_label_url"), + "emails": ("marketing_email", "feedback_email"), + "social": ("linkedin_url", "youtube_url"), + "location": ("city[]", "country[]", "latitude", "longitude", "zip_code", "street_address"), + "timestamps": ("created_at", "updated_at"), + } + + +def test_filters(): + assert CapyAppAcademySerializer.filters == ( + "name", + "slug", + "legal_name", + "status", + "created_at", + "available_as_saas", + ) + + +def test_path(): + assert CapyAppAcademySerializer.path == "/v1/auth/app/academy" + + +def test_model(): + assert CapyAppAcademySerializer.model == Academy + + +def test_references(): + serializer = CapyAppAcademySerializer() + + result = {} + for field in dir(serializer): + if field.startswith("_"): + continue + + if isinstance(x := getattr(serializer, field), capy.Serializer): + result[field] = x.__module__ + "." + x.__class__.__name__ + + assert result == { + "city": "breathecode.authenticate.serializers.CapyAppCitySerializer", + "country": "breathecode.authenticate.serializers.CapyAppCountrySerializer", + } diff --git a/breathecode/authenticate/tests/serializers/tests_capy_app_city_serializer.py b/breathecode/authenticate/tests/serializers/tests_capy_app_city_serializer.py new file mode 100644 index 000000000..748bfed61 --- /dev/null +++ b/breathecode/authenticate/tests/serializers/tests_capy_app_city_serializer.py @@ -0,0 +1,42 @@ +import capyc.django.serializer as capy + +from breathecode.admissions.models import City +from breathecode.authenticate.serializers import CapyAppCitySerializer, CapyAppCountrySerializer + + +def test_is_capy_serializer(): + serializer = CapyAppCitySerializer() + assert isinstance(serializer, capy.Serializer) + + +def test_fields(): + assert CapyAppCitySerializer.fields == { + "default": ("id", "name", "country"), + "country": ("country[]",), + } + + +def test_filters(): + assert CapyAppCitySerializer.filters == ("name",) + + +def test_path(): + assert CapyAppCitySerializer.path == "/v1/auth/app/city" + + +def test_model(): + assert CapyAppCitySerializer.model == City + + +def test_references(): + serializer = CapyAppCitySerializer() + + result = {} + for field in dir(serializer): + if field.startswith("_"): + continue + + if isinstance(x := getattr(serializer, field), capy.Serializer): + result[field] = x.__module__ + "." + x.__class__.__name__ + + assert result == {"country": "breathecode.authenticate.serializers.CapyAppCountrySerializer"} diff --git a/breathecode/authenticate/tests/serializers/tests_capy_app_country_serializer.py b/breathecode/authenticate/tests/serializers/tests_capy_app_country_serializer.py new file mode 100644 index 000000000..99520eecf --- /dev/null +++ b/breathecode/authenticate/tests/serializers/tests_capy_app_country_serializer.py @@ -0,0 +1,44 @@ +import capyc.django.serializer as capy + +from breathecode.admissions.models import Country +from breathecode.authenticate.serializers import CapyAppCountrySerializer + + +def test_is_capy_serializer(): + serializer = CapyAppCountrySerializer() + assert isinstance(serializer, capy.Serializer) + + +def test_fields(): + assert CapyAppCountrySerializer.fields == { + "default": ("code", "name"), + } + + +def test_filters(): + assert CapyAppCountrySerializer.filters == ( + "code", + "name", + ) + + +def test_path(): + assert CapyAppCountrySerializer.path == "/v1/auth/app/country" + + +def test_model(): + assert CapyAppCountrySerializer.model == Country + + +def test_references(): + serializer = CapyAppCountrySerializer() + + result = {} + for field in dir(serializer): + if field.startswith("_"): + continue + + if isinstance(x := getattr(serializer, field), capy.Serializer): + result[field] = x.__module__ + "." + x.__class__.__name__ + + assert result == {} diff --git a/breathecode/authenticate/tests/serializers/tests_capy_app_profile_academy_serializer.py b/breathecode/authenticate/tests/serializers/tests_capy_app_profile_academy_serializer.py new file mode 100644 index 000000000..9d2b4581d --- /dev/null +++ b/breathecode/authenticate/tests/serializers/tests_capy_app_profile_academy_serializer.py @@ -0,0 +1,60 @@ +import capyc.django.serializer as capy + +from breathecode.authenticate.models import ProfileAcademy +from breathecode.authenticate.serializers import CapyAppProfileAcademySerializer + + +def test_is_capy_serializer(): + serializer = CapyAppProfileAcademySerializer() + assert isinstance(serializer, capy.Serializer) + + +def test_fields(): + assert CapyAppProfileAcademySerializer.fields == { + "default": ( + "id", + "first_name", + "last_name", + "status", + "email", + "phone", + "user", + "academy", + ), + "address": ("address",), + "academy": ("academy[]",), + "user": ("user[]",), + "timestamps": ( + "created_at", + "updated_at", + ), + } + + +def test_filters(): + assert CapyAppProfileAcademySerializer.filters == ("status", "email", "id") + + +def test_path(): + assert CapyAppProfileAcademySerializer.path == "/v1/auth/app/student" + + +def test_model(): + assert CapyAppProfileAcademySerializer.model == ProfileAcademy + + +def test_references(): + serializer = CapyAppProfileAcademySerializer() + + result = {} + for field in dir(serializer): + if field.startswith("_"): + continue + + if isinstance(x := getattr(serializer, field), capy.Serializer): + result[field] = x.__module__ + "." + x.__class__.__name__ + + assert result == { + "academy": "breathecode.authenticate.serializers.CapyAppAcademySerializer", + "user": "breathecode.authenticate.serializers.CapyAppUserSerializer", + } diff --git a/breathecode/authenticate/tests/serializers/tests_capy_app_user_serializer.py b/breathecode/authenticate/tests/serializers/tests_capy_app_user_serializer.py new file mode 100644 index 000000000..3bbeea798 --- /dev/null +++ b/breathecode/authenticate/tests/serializers/tests_capy_app_user_serializer.py @@ -0,0 +1,59 @@ +import capyc.django.serializer as capy + +from breathecode.authenticate.models import User +from breathecode.authenticate.serializers import CapyAppUserSerializer + + +def test_is_capy_serializer(): + serializer = CapyAppUserSerializer() + assert isinstance(serializer, capy.Serializer) + + +def test_fields(): + assert CapyAppUserSerializer.fields == { + "default": ( + "id", + "username", + "first_name", + "last_name", + "email", + ), + "timestamps": ( + "date_joined", + "last_login", + ), + } + + +def test_filters(): + assert CapyAppUserSerializer.filters == ( + "id", + "username", + "first_name", + "last_name", + "email", + "date_joined", + "last_login", + ) + + +def test_path(): + assert CapyAppUserSerializer.path == "/v1/auth/app/user" + + +def test_model(): + assert CapyAppUserSerializer.model == User + + +def test_references(): + serializer = CapyAppUserSerializer() + + result = {} + for field in dir(serializer): + if field.startswith("_"): + continue + + if isinstance(x := getattr(serializer, field), capy.Serializer): + result[field] = x.__module__ + "." + x.__class__.__name__ + + assert result == {} diff --git a/breathecode/admissions/tests/permissions/contexts/__init__.py b/breathecode/authenticate/tests/urls/v1/__init__.py similarity index 100% rename from breathecode/admissions/tests/permissions/contexts/__init__.py rename to breathecode/authenticate/tests/urls/v1/__init__.py diff --git a/breathecode/authenticate/tests/urls/tests_academy_html_invite.py b/breathecode/authenticate/tests/urls/v1/tests_academy_html_invite.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_html_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_html_invite.py index 2261e487a..758472f9f 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_html_invite.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_html_invite.py @@ -9,7 +9,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase # IMPORTANT: the loader.render_to_string in a function is inside of function render diff --git a/breathecode/authenticate/tests/urls/tests_academy_id_member.py b/breathecode/authenticate/tests/urls/v1/tests_academy_id_member.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_id_member.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_id_member.py index f62e1c005..1498198c2 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_id_member.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_id_member.py @@ -10,7 +10,7 @@ from breathecode.utils import capable_of -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase @capable_of("read_member") diff --git a/breathecode/authenticate/tests/urls/tests_academy_id_member_id.py b/breathecode/authenticate/tests/urls/v1/tests_academy_id_member_id.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_academy_id_member_id.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_id_member_id.py index 000c2e253..4448022ad 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_id_member_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_id_member_id.py @@ -8,10 +8,9 @@ from rest_framework import status from rest_framework.response import Response -from breathecode.services import datetime_to_iso_format from breathecode.utils import capable_of -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase @capable_of("read_member") diff --git a/breathecode/authenticate/tests/urls/tests_academy_invite_id.py b/breathecode/authenticate/tests/urls/v1/tests_academy_invite_id.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_invite_id.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_invite_id.py index 8ece39fe1..9cf6c846e 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_invite_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_invite_id.py @@ -10,7 +10,7 @@ from breathecode.utils import capable_of -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase @capable_of("invite_resend") diff --git a/breathecode/authenticate/tests/urls/tests_academy_member.py b/breathecode/authenticate/tests/urls/v1/tests_academy_member.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_member.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_member.py index 2fab6befa..0915f769d 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_member.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_member.py @@ -16,7 +16,7 @@ from breathecode.utils import capable_of from breathecode.utils.api_view_extensions.api_view_extension_handlers import APIViewExtensionHandlers -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase # the test have too must lines, that's split in many test suite diff --git a/breathecode/authenticate/tests/urls/tests_academy_member_id.py b/breathecode/authenticate/tests/urls/v1/tests_academy_member_id.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_member_id.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_member_id.py index 2d803a01a..46fdb94a9 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_member_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_member_id.py @@ -11,7 +11,7 @@ from breathecode.services import datetime_to_iso_format from breathecode.utils import capable_of -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase @capable_of("read_member") diff --git a/breathecode/authenticate/tests/urls/tests_academy_member_id_invite.py b/breathecode/authenticate/tests/urls/v1/tests_academy_member_id_invite.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_member_id_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_member_id_invite.py index 6a14d0969..50eb21209 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_member_id_invite.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_member_id_invite.py @@ -9,7 +9,7 @@ import breathecode.notify.actions as actions from breathecode.tests.mocks.requests import apply_requests_post_mock -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def generate_user_invite(self, model, user_invite, arguments={}): diff --git a/breathecode/authenticate/tests/urls/tests_academy_student.py b/breathecode/authenticate/tests/urls/v1/tests_academy_student.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_student.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_student.py index ad3cbc048..ff11ff68c 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_student.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_student.py @@ -4,7 +4,6 @@ import os import urllib.parse -from random import choice from unittest.mock import MagicMock, call, patch from django.urls.base import reverse_lazy @@ -14,8 +13,7 @@ import breathecode.notify.actions as actions from breathecode.utils.api_view_extensions.api_view_extension_handlers import APIViewExtensionHandlers -from ...models import ProfileAcademy -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase PROFILE_ACADEMY_STATUS = [ "INVITED", diff --git a/breathecode/authenticate/tests/urls/tests_academy_student_id.py b/breathecode/authenticate/tests/urls/v1/tests_academy_student_id.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_student_id.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_student_id.py index 9376e014b..b80cc6ce2 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_student_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_student_id.py @@ -9,7 +9,7 @@ from breathecode.services import datetime_to_iso_format -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_academy_token.py b/breathecode/authenticate/tests/urls/v1/tests_academy_token.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_token.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_token.py index a407cb3c2..4dc1c18b4 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_token.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_token.py @@ -3,9 +3,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from breathecode.services import datetime_to_iso_format - -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_academy_user_invite.py b/breathecode/authenticate/tests/urls/v1/tests_academy_user_invite.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_academy_user_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_user_invite.py index 15217a88a..4b7b7051d 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_user_invite.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_user_invite.py @@ -7,9 +7,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from breathecode.authenticate.models import ProfileAcademy - -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase STATUSES = [ "PENDING", diff --git a/breathecode/authenticate/tests/urls/tests_academy_user_me_invite.py b/breathecode/authenticate/tests/urls/v1/tests_academy_user_me_invite.py similarity index 97% rename from breathecode/authenticate/tests/urls/tests_academy_user_me_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_user_me_invite.py index 81ce58017..fb2dc6659 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_user_me_invite.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_user_me_invite.py @@ -2,14 +2,13 @@ Set of tests for MeInviteView, this include duck tests """ -from random import choice from unittest.mock import MagicMock, patch from django.urls.base import reverse_lazy from rest_framework import status from rest_framework.response import Response -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def view_method_mock(request, *args, **kwargs): diff --git a/breathecode/authenticate/tests/urls/tests_academy_user_me_invite_status.py b/breathecode/authenticate/tests/urls/v1/tests_academy_user_me_invite_status.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_academy_user_me_invite_status.py rename to breathecode/authenticate/tests/urls/v1/tests_academy_user_me_invite_status.py index 104703125..adcbc630f 100644 --- a/breathecode/authenticate/tests/urls/tests_academy_user_me_invite_status.py +++ b/breathecode/authenticate/tests/urls/v1/tests_academy_user_me_invite_status.py @@ -2,14 +2,13 @@ Set of tests for MeInviteView, this include duck tests """ -from random import choice from unittest.mock import MagicMock, patch from django.urls.base import reverse_lazy from rest_framework import status from rest_framework.response import Response -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def view_method_mock(request, *args, **kwargs): diff --git a/breathecode/authenticate/tests/urls/tests_app_token.py b/breathecode/authenticate/tests/urls/v1/tests_app_token.py similarity index 100% rename from breathecode/authenticate/tests/urls/tests_app_token.py rename to breathecode/authenticate/tests/urls/v1/tests_app_token.py diff --git a/breathecode/authenticate/tests/urls/tests_app_user.py b/breathecode/authenticate/tests/urls/v1/tests_app_user.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_app_user.py rename to breathecode/authenticate/tests/urls/v1/tests_app_user.py index 51284a072..bb58af90f 100644 --- a/breathecode/authenticate/tests/urls/tests_app_user.py +++ b/breathecode/authenticate/tests/urls/v1/tests_app_user.py @@ -8,7 +8,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def credentials_github_serializer(credentials_github): diff --git a/breathecode/authenticate/tests/urls/tests_app_user_id.py b/breathecode/authenticate/tests/urls/v1/tests_app_user_id.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_app_user_id.py rename to breathecode/authenticate/tests/urls/v1/tests_app_user_id.py index 664dbe277..e3300e592 100644 --- a/breathecode/authenticate/tests/urls/tests_app_user_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_app_user_id.py @@ -8,7 +8,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def credentials_github_serializer(credentials_github): diff --git a/breathecode/authenticate/tests/urls/tests_app_webhook.py b/breathecode/authenticate/tests/urls/v1/tests_app_webhook.py similarity index 100% rename from breathecode/authenticate/tests/urls/tests_app_webhook.py rename to breathecode/authenticate/tests/urls/v1/tests_app_webhook.py diff --git a/breathecode/authenticate/tests/urls/tests_appuseragreement.py b/breathecode/authenticate/tests/urls/v1/tests_appuseragreement.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_appuseragreement.py rename to breathecode/authenticate/tests/urls/v1/tests_appuseragreement.py index d550e509d..b8b18e41c 100644 --- a/breathecode/authenticate/tests/urls/tests_appuseragreement.py +++ b/breathecode/authenticate/tests/urls/v1/tests_appuseragreement.py @@ -3,8 +3,6 @@ """ import random -from datetime import timedelta -from unittest.mock import MagicMock, patch from django.urls.base import reverse_lazy from django.utils import timezone @@ -12,7 +10,7 @@ from breathecode.tests.mixins.breathecode_mixin.breathecode import fake -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase UTC_NOW = timezone.now() TOKEN = fake.name() diff --git a/breathecode/authenticate/tests/urls/tests_confirmation_token.py b/breathecode/authenticate/tests/urls/v1/tests_confirmation_token.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_confirmation_token.py rename to breathecode/authenticate/tests/urls/v1/tests_confirmation_token.py index 4127405fa..f58a37d5f 100644 --- a/breathecode/authenticate/tests/urls/tests_confirmation_token.py +++ b/breathecode/authenticate/tests/urls/v1/tests_confirmation_token.py @@ -3,22 +3,12 @@ """ import os -import random -import re -from unittest.mock import MagicMock, patch, call -from django.urls.base import reverse_lazy -from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase -from rest_framework import status -from rest_framework.response import Response -from django.template import loader - -from breathecode.utils import capable_of -from breathecode.tests.mocks import apply_requests_post_mock -from datetime import timedelta +from django.template import loader +from django.urls.base import reverse_lazy from django.utils import timezone -from breathecode.notify import actions + +from ...mixins.new_auth_test_case import AuthTestCase UTC_NOW = timezone.now() diff --git a/breathecode/authenticate/tests/urls/tests_github.py b/breathecode/authenticate/tests/urls/v1/tests_github.py similarity index 97% rename from breathecode/authenticate/tests/urls/tests_github.py rename to breathecode/authenticate/tests/urls/v1/tests_github.py index 7a224666e..d2aec5d3b 100644 --- a/breathecode/authenticate/tests/urls/tests_github.py +++ b/breathecode/authenticate/tests/urls/v1/tests_github.py @@ -2,11 +2,13 @@ Test cases for /user """ -import urllib import os +import urllib + from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins import AuthTestCase + +from ...mixins import AuthTestCase # from ..mocks import GithubRequestsMock diff --git a/breathecode/authenticate/tests/urls/tests_github_callback.py b/breathecode/authenticate/tests/urls/v1/tests_github_callback.py similarity index 64% rename from breathecode/authenticate/tests/urls/tests_github_callback.py rename to breathecode/authenticate/tests/urls/v1/tests_github_callback.py index b539ef37a..8f190c795 100644 --- a/breathecode/authenticate/tests/urls/tests_github_callback.py +++ b/breathecode/authenticate/tests/urls/v1/tests_github_callback.py @@ -6,22 +6,68 @@ import urllib from unittest import mock +import capyc.pytest as capy import pytest from django.template import loader from django.urls.base import reverse_lazy from rest_framework import status from rest_framework.test import APIClient +import staging.pytest as staging from breathecode.authenticate.tests.mocks.mocks import FakeResponse from breathecode.tests.mixins.breathecode_mixin.breathecode import Breathecode -from ...models import Role -from ..mixins.new_auth_test_case import AuthTestCase -from ..mocks import GithubRequestsMock +from ...mocks import GithubRequestsMock + + +@pytest.fixture +def github_token(fake: capy.Fake): + yield fake.slug() @pytest.fixture(autouse=True) -def setup(db, monkeypatch): +def setup( + db, + monkeypatch: pytest.MonkeyPatch, + http: staging.HTTP, + github_user: dict, + github_user_emails: list[str, dict], + github_token: str, +): + + http.post( + "https://github.com/login/oauth/access_token", + data={ + "client_id": "123456", + "client_secret": "123456", + "redirect_uri": "https://breathecode.herokuapp.com/v1/auth/github/callback", + "code": "Konan", + }, + headers={"Accept": "application/json"}, + timeout=30, + ).response( + {"access_token": github_token, "scope": "repo,gist", "token_type": "bearer"}, + status=200, + ) + + http.get( + "https://api.github.com/user", + headers={"Authorization": f"token {github_token}"}, + timeout=30, + ).response( + github_user, + status=200, + ) + + http.get( + "https://api.github.com/user/emails", + headers={"Authorization": f"token {github_token}"}, + timeout=30, + ).response( + github_user_emails, + status=200, + ) + routes = { "https://github.com/login/oauth/access_token": FakeResponse( status_code=200, @@ -39,6 +85,12 @@ def post_mock(url, *args, **kwargs): monkeypatch.setattr( "breathecode.admissions.signals.student_edu_status_updated.send_robust", mock.MagicMock(return_value=None) ) + + monkeypatch.setenv("GITHUB_CLIENT_ID", "123456") + monkeypatch.setenv("GITHUB_SECRET", "123456") + monkeypatch.setenv("GITHUB_REDIRECT_URL", "https://breathecode.herokuapp.com/v1/auth/github/callback") + monkeypatch.setattr("breathecode.authenticate.tasks.async_validate_email_invite", mock.MagicMock(return_value=None)) + yield @@ -52,6 +104,67 @@ def render(message): ) +@pytest.fixture +def github_user(fake: capy.Fake): + return { + "login": fake.user_name(), + "id": 3018142, + "node_id": fake.slug(), + "avatar_url": fake.image_url(), + "gravatar_id": "", + "url": fake.url(), + "html_url": fake.url(), + "followers_url": fake.url(), + "following_url": fake.url(), + "gists_url": fake.url(), + "starred_url": fake.url(), + "subscriptions_url": fake.url(), + "organizations_url": fake.url(), + "repos_url": fake.url(), + "events_url": fake.url(), + "received_events_url": fake.url(), + "type": "User", + "user_view_type": "private", + "site_admin": False, + "name": None, + "company": "@" + fake.user_name(), + "blog": fake.url(), + "location": None, + "email": None, + "hireable": None, + "bio": fake.paragraph(), + "twitter_username": "@" + fake.user_name(), + "notification_email": None, + "public_repos": 0, + "public_gists": 0, + "followers": 0, + "following": 0, + "created_at": "2024-12-18T22:50:38Z", + "updated_at": "2024-12-18T22:50:41Z", + "private_gists": 0, + "total_private_repos": 0, + "owned_private_repos": 0, + "disk_usage": 0, + "collaborators": 0, + "two_factor_authentication": False, + "plan": {"name": "free", "space": 123456789, "collaborators": 0, "private_repos": 123456789}, + } + + +def pick_github_data(data, fields=[], overwrite={}): + result = {} + + for field in fields: + result[overwrite.get(field, field)] = data[field] + + return result + + +@pytest.fixture +def github_user_emails(fake: capy.Fake): + return [{"email": fake.email(), "primary": True, "verified": True, "visibility": "public"}] + + def get_profile_fields(data={}): return { "id": 1, @@ -143,10 +256,12 @@ def test_github_callback__user_not_exist(bc: Breathecode, client: APIClient): assert bc.database.list_of("authenticate.ProfileAcademy") == [] -def test_github_callback__user_not_exist_but_waiting_list(bc: Breathecode, client: APIClient): +def test_github_callback__user_not_exist_but_waiting_list( + bc: Breathecode, client: APIClient, github_user_emails: list[str, dict] +): """Test /github/callback""" - user_invite = {"status": "WAITING_LIST", "email": "jdefreitaspinto@gmail.com"} + user_invite = {"status": "WAITING_LIST", "email": github_user_emails[0]["email"]} bc.database.create(user_invite=user_invite) original_url_callback = "https://google.co.ve" @@ -179,7 +294,7 @@ def test_github_callback__user_not_exist_but_waiting_list(bc: Breathecode, clien assert bc.database.list_of("authenticate.ProfileAcademy") == [] -def test_github_callback__with_user(bc: Breathecode, client: APIClient): +def test_github_callback__with_user(bc: Breathecode, client: APIClient, github_token: str): """Test /github/callback""" user_kwargs = {"email": "JDEFREITASPINTO@GMAIL.COM"} role_kwargs = {"slug": "student", "name": "Student"} @@ -200,16 +315,22 @@ def test_github_callback__with_user(bc: Breathecode, client: APIClient): assert bc.database.list_of("authenticate.Profile") == [] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), ] -def test_github_callback__with_user__with_email_in_uppercase(bc: Breathecode, client: APIClient): +def test_github_callback__with_user__with_email_in_uppercase( + bc: Breathecode, client: APIClient, github_user: dict, github_token: str, github_user_emails: list[str, dict] +): """Test /github/callback""" - user_kwargs = {"email": "JDEFREITASPINTO@GMAIL.COM"} + user_kwargs = {"email": github_user_emails[0]["email"].upper()} role_kwargs = {"slug": "student", "name": "Student"} model = bc.database.create(role=True, user=True, user_kwargs=user_kwargs, role_kwargs=role_kwargs) @@ -221,21 +342,41 @@ def test_github_callback__with_user__with_email_in_uppercase(bc: Breathecode, cl params = {"url": original_url_callback, "code": code} response = client.get(f"{url}?{urllib.parse.urlencode(params)}") + with open("content.html", "w") as f: + f.write(bc.format.from_bytes(response.content)) + assert response.status_code == status.HTTP_302_FOUND assert bool(token_pattern.match(response.url)) == True assert bc.database.list_of("auth.User") == [{**bc.format.to_dict(model.user)}] - assert bc.database.list_of("authenticate.Profile") == [get_profile_fields(data={})] + assert bc.database.list_of("authenticate.Profile") == [ + get_profile_fields( + data={ + **pick_github_data(github_user, fields=["blog", "bio", "avatar_url", "twitter_username"]), + } + ), + ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [] -def test_github_callback__with_bad_user_in_querystring(bc: Breathecode, client: APIClient): +def test_github_callback__with_bad_user_in_querystring( + bc: Breathecode, client: APIClient, github_user_emails: list[str, dict] +): """Test /github/callback""" - user_kwargs = {"email": "JDEFREITASPINTO@GMAIL.COM"} + user_kwargs = {"email": github_user_emails[0]["email"].upper()} role_kwargs = {"slug": "student", "name": "Student"} model = bc.database.create( role=True, user=True, profile_academy=True, user_kwargs=user_kwargs, role_kwargs=role_kwargs, token=True @@ -260,7 +401,12 @@ def test_github_callback__with_bad_user_in_querystring(bc: Breathecode, client: ] -def test_github_callback__with_user(bc: Breathecode, client: APIClient): +def test_github_callback__with_user( + bc: Breathecode, + client: APIClient, + github_user: dict, + github_token: str, +): """Test /github/callback""" user_kwargs = {"email": "JDEFREITASPINTO@GMAIL.COM"} role_kwargs = {"slug": "student", "name": "Student"} @@ -283,16 +429,36 @@ def test_github_callback__with_user(bc: Breathecode, client: APIClient): assert bc.database.list_of("auth.User") == [{**bc.format.to_dict(model.user)}] - assert bc.database.list_of("authenticate.Profile") == [get_profile_fields(data={})] + assert bc.database.list_of("authenticate.Profile") == [ + get_profile_fields( + data={ + **pick_github_data(github_user, fields=["blog", "bio", "avatar_url", "twitter_username"]), + } + ), + ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), ] -def test_github_callback__with_user__profile_without_avatar_url(bc: Breathecode, client: APIClient): +def test_github_callback__with_user__profile_without_avatar_url( + bc: Breathecode, + client: APIClient, + github_user: dict, + github_token: str, +): """Test /github/callback""" user_kwargs = {"email": "JDEFREITASPINTO@GMAIL.COM"} role_kwargs = {"slug": "student", "name": "Student"} @@ -322,17 +488,37 @@ def test_github_callback__with_user__profile_without_avatar_url(bc: Breathecode, assert bc.database.list_of("auth.User") == [{**bc.format.to_dict(model.user)}] assert bc.database.list_of("authenticate.Profile") == [ - get_profile_fields(data={"bio": None, "blog": None}), + get_profile_fields( + data={ + "bio": None, + "blog": None, + **pick_github_data(github_user, fields=["avatar_url"]), + } + ), ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), ] -def test_github_callback__with_user__profile_with_avatar_url(bc: Breathecode, client: APIClient): +def test_github_callback__with_user__profile_with_avatar_url( + bc: Breathecode, + client: APIClient, + github_user: dict, + github_token: str, +): """Test /github/callback""" user_kwargs = {"email": "JDEFREITASPINTO@GMAIL.COM"} role_kwargs = {"slug": "student", "name": "Student"} @@ -363,11 +549,25 @@ def test_github_callback__with_user__profile_with_avatar_url(bc: Breathecode, cl assert bc.database.list_of("auth.User") == [{**bc.format.to_dict(model.user)}] assert bc.database.list_of("authenticate.Profile") == [ - get_profile_fields(data={"bio": None, "blog": None, **profile}), + get_profile_fields( + data={ + "bio": None, + "blog": None, + **profile, + } + ), ] - assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), @@ -375,7 +575,10 @@ def test_github_callback__with_user__profile_with_avatar_url(bc: Breathecode, cl def test_github_callback__with_user_different_email__without_credetials_of_github__without_cohort_user( - bc: Breathecode, client: APIClient + bc: Breathecode, + client: APIClient, + github_user: dict, + github_token: str, ): """Test /github/callback""" user = {"email": "FJOSE123@GMAIL.COM"} @@ -397,9 +600,24 @@ def test_github_callback__with_user_different_email__without_credetials_of_githu assert bc.database.list_of("auth.User") == [{**bc.format.to_dict(model.user)}] - assert bc.database.list_of("authenticate.Profile") == [get_profile_fields(data={})] + assert bc.database.list_of("authenticate.Profile") == [ + get_profile_fields( + data={ + **pick_github_data(github_user, fields=["blog", "bio", "avatar_url", "twitter_username"]), + } + ), + ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), @@ -407,7 +625,10 @@ def test_github_callback__with_user_different_email__without_credetials_of_githu def test_github_callback__with_user_different_email__without_credetials_of_github__with_cohort_user( - bc: Breathecode, client: APIClient + bc: Breathecode, + client: APIClient, + github_user: dict, + github_token: str, ): """Test /github/callback""" user = {"email": "FJOSE123@GMAIL.COM"} @@ -429,9 +650,24 @@ def test_github_callback__with_user_different_email__without_credetials_of_githu assert bc.database.list_of("auth.User") == [{**bc.format.to_dict(model.user)}] - assert bc.database.list_of("authenticate.Profile") == [get_profile_fields(data={})] + assert bc.database.list_of("authenticate.Profile") == [ + get_profile_fields( + data={ + **pick_github_data(github_user, fields=["blog", "bio", "avatar_url", "twitter_username"]), + } + ), + ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(), + get_credentials_github_fields( + data={ + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), @@ -439,7 +675,10 @@ def test_github_callback__with_user_different_email__without_credetials_of_githu def test_github_callback__with_user_different_email__with_credentials_of_github__without_cohort_user( - bc: Breathecode, client: APIClient + bc: Breathecode, + client: APIClient, + github_user: dict, + github_token: str, ): """Test /github/callback""" users = [{"email": "FJOSE123@GMAIL.COM"}, {"email": "jdefreitaspinto@gmail.com"}] @@ -466,10 +705,25 @@ def test_github_callback__with_user_different_email__with_credentials_of_github_ assert bc.database.list_of("auth.User") == bc.format.to_dict(model.user) assert bc.database.list_of("authenticate.Profile") == [ - get_profile_fields(data={"user_id": 2}), + get_profile_fields( + data={ + "user_id": 2, + **pick_github_data(github_user, fields=["blog", "bio", "avatar_url", "twitter_username"]), + } + ), ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(data={"user_id": 2}), + get_credentials_github_fields( + data={ + "user_id": 2, + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ bc.format.to_dict(model.profile_academy), @@ -477,9 +731,13 @@ def test_github_callback__with_user_different_email__with_credentials_of_github_ def test_github_callback__with_user_different_email__with_credentials_of_github__with_cohort_user( - bc: Breathecode, client: APIClient + bc: Breathecode, + client: APIClient, + http: staging.HTTP, + github_user: dict, + github_token: str, ): - """Test /github/callback""" + users = [{"email": "FJOSE123@GMAIL.COM"}, {"email": "jdefreitaspinto@gmail.com"}] role = {"slug": "student", "name": "Student"} credentials_github = {"github_id": 3018142} @@ -494,6 +752,16 @@ def test_github_callback__with_user_different_email__with_credentials_of_github_ token=token, ) + http.post( + "https://rigobot.herokuapp.com/v1/auth/invite", + data={"organization": "4geeks", "user_token": model.token.key}, + headers={"Accept": "application/json"}, + timeout=30, + ).response( + {}, + status=200, + ) + original_url_callback = "https://google.co.ve" token_pattern = re.compile("^" + original_url_callback.replace(".", r"\.") + r"\?token=[0-9a-zA-Z]{,40}$") code = "Konan" @@ -510,10 +778,25 @@ def test_github_callback__with_user_different_email__with_credentials_of_github_ assert bc.database.list_of("auth.User") == bc.format.to_dict(model.user) assert bc.database.list_of("authenticate.Profile") == [ - get_profile_fields(data={"user_id": 2}), + get_profile_fields( + data={ + "user_id": 2, + **pick_github_data(github_user, fields=["blog", "bio", "avatar_url", "twitter_username"]), + } + ), ] assert bc.database.list_of("authenticate.CredentialsGithub") == [ - get_credentials_github_fields(data={"user_id": 2}), + get_credentials_github_fields( + data={ + "user_id": 2, + "token": github_token, + **pick_github_data( + github_user, + fields=["blog", "bio", "avatar_url", "twitter_username", "login", "company", "name", "email"], + overwrite={"login": "username"}, + ), + } + ), ] assert bc.database.list_of("authenticate.ProfileAcademy") == [ diff --git a/breathecode/authenticate/tests/urls/tests_github_me.py b/breathecode/authenticate/tests/urls/v1/tests_github_me.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_github_me.py rename to breathecode/authenticate/tests/urls/v1/tests_github_me.py index 6563abcf7..5a79d8ed7 100644 --- a/breathecode/authenticate/tests/urls/tests_github_me.py +++ b/breathecode/authenticate/tests/urls/v1/tests_github_me.py @@ -5,7 +5,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_github_token.py b/breathecode/authenticate/tests/urls/v1/tests_github_token.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_github_token.py rename to breathecode/authenticate/tests/urls/v1/tests_github_token.py index 4d2eac2b0..a854b618d 100644 --- a/breathecode/authenticate/tests/urls/tests_github_token.py +++ b/breathecode/authenticate/tests/urls/v1/tests_github_token.py @@ -2,13 +2,13 @@ Test cases for /user """ -import urllib import os +import urllib + from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase -# from ..mocks import GithubRequestsMock +from ...mixins.new_auth_test_case import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_google_callback.py b/breathecode/authenticate/tests/urls/v1/tests_google_callback.py similarity index 100% rename from breathecode/authenticate/tests/urls/tests_google_callback.py rename to breathecode/authenticate/tests/urls/v1/tests_google_callback.py diff --git a/breathecode/authenticate/tests/urls/tests_google_token.py b/breathecode/authenticate/tests/urls/v1/tests_google_token.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_google_token.py rename to breathecode/authenticate/tests/urls/v1/tests_google_token.py index 62e2586dd..78d5d7cff 100644 --- a/breathecode/authenticate/tests/urls/tests_google_token.py +++ b/breathecode/authenticate/tests/urls/v1/tests_google_token.py @@ -3,7 +3,6 @@ """ from typing import Any -from unittest.mock import MagicMock from urllib.parse import urlencode import capyc.pytest as capy diff --git a/breathecode/authenticate/tests/urls/tests_google_webhook.py b/breathecode/authenticate/tests/urls/v1/tests_google_webhook.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_google_webhook.py rename to breathecode/authenticate/tests/urls/v1/tests_google_webhook.py index 1a9effcf6..0a0f79ca0 100644 --- a/breathecode/authenticate/tests/urls/tests_google_webhook.py +++ b/breathecode/authenticate/tests/urls/v1/tests_google_webhook.py @@ -6,7 +6,6 @@ import hashlib import hmac import os -from unittest.mock import MagicMock, call import capyc.pytest as capy import pytest @@ -14,8 +13,6 @@ from django.utils import timezone from rest_framework import status -from breathecode.payments.tasks import process_google_webhook - now = timezone.now() diff --git a/breathecode/authenticate/tests/urls/tests_invite_resend_id.py b/breathecode/authenticate/tests/urls/v1/tests_invite_resend_id.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_invite_resend_id.py rename to breathecode/authenticate/tests/urls/v1/tests_invite_resend_id.py index cf33406f2..74511de36 100644 --- a/breathecode/authenticate/tests/urls/tests_invite_resend_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_invite_resend_id.py @@ -4,20 +4,15 @@ import os import random -import re from datetime import timedelta from unittest.mock import MagicMock, call, patch from django.urls.base import reverse_lazy from django.utils import timezone -from rest_framework import status -from rest_framework.response import Response from breathecode.notify import actions -from breathecode.tests.mocks import apply_requests_post_mock -from breathecode.utils import capable_of -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase UTC_NOW = timezone.now() diff --git a/breathecode/authenticate/tests/urls/tests_login.py b/breathecode/authenticate/tests/urls/v1/tests_login.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_login.py rename to breathecode/authenticate/tests/urls/v1/tests_login.py index 80b4d08d6..004bc9b73 100644 --- a/breathecode/authenticate/tests/urls/tests_login.py +++ b/breathecode/authenticate/tests/urls/v1/tests_login.py @@ -3,12 +3,15 @@ """ from unittest.mock import MagicMock, call, patch -from rest_framework import status -from django.urls.base import reverse_lazy + from django.contrib.auth.hashers import make_password -from ..mixins.new_auth_test_case import AuthTestCase +from django.urls.base import reverse_lazy +from rest_framework import status + from breathecode.activity import tasks as activity_tasks +from ...mixins.new_auth_test_case import AuthTestCase + def user_invite_serializer(self, user_invite, academy=None, cohort=None): return { diff --git a/breathecode/authenticate/tests/urls/tests_logout.py b/breathecode/authenticate/tests/urls/v1/tests_logout.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_logout.py rename to breathecode/authenticate/tests/urls/v1/tests_logout.py index 61919454e..8ec56aaf6 100644 --- a/breathecode/authenticate/tests/urls/tests_logout.py +++ b/breathecode/authenticate/tests/urls/v1/tests_logout.py @@ -2,10 +2,10 @@ Test cases for /user """ -import re from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins import AuthTestCase + +from ...mixins import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_me_app_slug_sync.py b/breathecode/authenticate/tests/urls/v1/tests_me_app_slug_sync.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_me_app_slug_sync.py rename to breathecode/authenticate/tests/urls/v1/tests_me_app_slug_sync.py index 4dd56a93c..3c7aba1c3 100644 --- a/breathecode/authenticate/tests/urls/tests_me_app_slug_sync.py +++ b/breathecode/authenticate/tests/urls/v1/tests_me_app_slug_sync.py @@ -4,7 +4,7 @@ import json import random -from unittest.mock import AsyncMock, MagicMock, call, patch +from unittest.mock import MagicMock, call import aiohttp import pytest diff --git a/breathecode/authenticate/tests/urls/tests_me_profile_academy_invite.py b/breathecode/authenticate/tests/urls/v1/tests_me_profile_academy_invite.py similarity index 100% rename from breathecode/authenticate/tests/urls/tests_me_profile_academy_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_me_profile_academy_invite.py diff --git a/breathecode/authenticate/tests/urls/tests_member_invite.py b/breathecode/authenticate/tests/urls/v1/tests_member_invite.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_member_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_member_invite.py index 9c981a185..8906d3f7c 100644 --- a/breathecode/authenticate/tests/urls/tests_member_invite.py +++ b/breathecode/authenticate/tests/urls/v1/tests_member_invite.py @@ -9,7 +9,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase # IMPORTANT: the loader.render_to_string in a function is inside of function render diff --git a/breathecode/authenticate/tests/urls/tests_member_invite_resend_id.py b/breathecode/authenticate/tests/urls/v1/tests_member_invite_resend_id.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_member_invite_resend_id.py rename to breathecode/authenticate/tests/urls/v1/tests_member_invite_resend_id.py index ddc8bf25f..8f6a4cf55 100644 --- a/breathecode/authenticate/tests/urls/tests_member_invite_resend_id.py +++ b/breathecode/authenticate/tests/urls/v1/tests_member_invite_resend_id.py @@ -3,7 +3,6 @@ """ import os -import re from datetime import timedelta from unittest.mock import MagicMock, patch @@ -15,7 +14,7 @@ from breathecode.tests.mocks import apply_requests_post_mock from breathecode.utils import capable_of -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase @capable_of("invite_resend") diff --git a/breathecode/authenticate/tests/urls/tests_member_invite_token.py b/breathecode/authenticate/tests/urls/v1/tests_member_invite_token.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_member_invite_token.py rename to breathecode/authenticate/tests/urls/v1/tests_member_invite_token.py index 086f9d99a..d5945a395 100644 --- a/breathecode/authenticate/tests/urls/tests_member_invite_token.py +++ b/breathecode/authenticate/tests/urls/v1/tests_member_invite_token.py @@ -17,7 +17,7 @@ from breathecode.authenticate.forms import InviteForm from breathecode.payments.tasks import build_plan_financing -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase CSRF_TOKEN = str(randint(10000, 10000000000000)) render_to_string = loader.render_to_string diff --git a/breathecode/authenticate/tests/urls/tests_password_form.py b/breathecode/authenticate/tests/urls/v1/tests_password_form.py similarity index 100% rename from breathecode/authenticate/tests/urls/tests_password_form.py rename to breathecode/authenticate/tests/urls/v1/tests_password_form.py diff --git a/breathecode/authenticate/tests/urls/tests_password_reset.py b/breathecode/authenticate/tests/urls/v1/tests_password_reset.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_password_reset.py rename to breathecode/authenticate/tests/urls/v1/tests_password_reset.py index ab0c8f1f1..ae164193e 100644 --- a/breathecode/authenticate/tests/urls/tests_password_reset.py +++ b/breathecode/authenticate/tests/urls/v1/tests_password_reset.py @@ -10,7 +10,7 @@ from breathecode.authenticate.models import Token -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_password_token.py b/breathecode/authenticate/tests/urls/v1/tests_password_token.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_password_token.py rename to breathecode/authenticate/tests/urls/v1/tests_password_token.py index 617274def..008b653d3 100644 --- a/breathecode/authenticate/tests/urls/tests_password_token.py +++ b/breathecode/authenticate/tests/urls/v1/tests_password_token.py @@ -5,7 +5,6 @@ import os import random import string -from random import randint from unittest.mock import MagicMock, patch from django.core.handlers.wsgi import WSGIRequest @@ -17,7 +16,7 @@ from breathecode.authenticate.forms import PickPasswordForm -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def set_password(self, raw_password): diff --git a/breathecode/authenticate/tests/urls/tests_profile_academy_github_reset_link.py b/breathecode/authenticate/tests/urls/v1/tests_profile_academy_github_reset_link.py similarity index 96% rename from breathecode/authenticate/tests/urls/tests_profile_academy_github_reset_link.py rename to breathecode/authenticate/tests/urls/v1/tests_profile_academy_github_reset_link.py index d63845c5b..b1097c309 100644 --- a/breathecode/authenticate/tests/urls/tests_profile_academy_github_reset_link.py +++ b/breathecode/authenticate/tests/urls/v1/tests_profile_academy_github_reset_link.py @@ -1,9 +1,9 @@ -from breathecode.authenticate.models import ProfileAcademy, Token -import re from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase -from breathecode.services import datetime_to_iso_format + +from breathecode.authenticate.models import ProfileAcademy, Token + +from ...mixins.new_auth_test_case import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_profile_invite_me.py b/breathecode/authenticate/tests/urls/v1/tests_profile_invite_me.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_profile_invite_me.py rename to breathecode/authenticate/tests/urls/v1/tests_profile_invite_me.py index 3898c0053..ad7424fef 100644 --- a/breathecode/authenticate/tests/urls/tests_profile_invite_me.py +++ b/breathecode/authenticate/tests/urls/v1/tests_profile_invite_me.py @@ -7,9 +7,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from breathecode.services import datetime_to_iso_format - -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def get_serializer(self, mentor_profile, academy, mentorship_service, user): diff --git a/breathecode/authenticate/tests/urls/tests_profile_me.py b/breathecode/authenticate/tests/urls/v1/tests_profile_me.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_profile_me.py rename to breathecode/authenticate/tests/urls/v1/tests_profile_me.py index 0b8977ddc..9cff1c139 100644 --- a/breathecode/authenticate/tests/urls/tests_profile_me.py +++ b/breathecode/authenticate/tests/urls/v1/tests_profile_me.py @@ -3,9 +3,11 @@ """ import random + from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase + +from ...mixins.new_auth_test_case import AuthTestCase def get_serializer(profile, user): diff --git a/breathecode/authenticate/tests/urls/tests_profile_me_picture.py b/breathecode/authenticate/tests/urls/v1/tests_profile_me_picture.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_profile_me_picture.py rename to breathecode/authenticate/tests/urls/v1/tests_profile_me_picture.py index e14f6b744..468de1080 100644 --- a/breathecode/authenticate/tests/urls/tests_profile_me_picture.py +++ b/breathecode/authenticate/tests/urls/v1/tests_profile_me_picture.py @@ -2,18 +2,16 @@ Test cases for /academy/:id/member/:id """ -import os import random from unittest.mock import MagicMock, PropertyMock, call, patch -import numpy as np from django.urls.base import reverse_lazy from rest_framework import status from breathecode.services.google_cloud.storage import File, Storage from breathecode.tests.mocks.requests import apply_requests_request_mock -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase SHAPE_OF_URL = "https://us-central1-labor-day-story.cloudfunctions.net/shape-of-image" diff --git a/breathecode/authenticate/tests/urls/tests_slack.py b/breathecode/authenticate/tests/urls/v1/tests_slack.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_slack.py rename to breathecode/authenticate/tests/urls/v1/tests_slack.py index 2386d7377..750e3725f 100644 --- a/breathecode/authenticate/tests/urls/tests_slack.py +++ b/breathecode/authenticate/tests/urls/v1/tests_slack.py @@ -9,7 +9,7 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins import AuthTestCase +from ...mixins import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_slack_callback.py b/breathecode/authenticate/tests/urls/v1/tests_slack_callback.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_slack_callback.py rename to breathecode/authenticate/tests/urls/v1/tests_slack_callback.py index 5242af105..e0a34306c 100644 --- a/breathecode/authenticate/tests/urls/tests_slack_callback.py +++ b/breathecode/authenticate/tests/urls/v1/tests_slack_callback.py @@ -5,10 +5,12 @@ import base64 import urllib from unittest import mock + from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins import AuthTestCase, SlackTestCase -from ..mocks import SlackRequestsMock + +from ...mixins import AuthTestCase, SlackTestCase +from ...mocks import SlackRequestsMock class AuthenticateTestSuite(AuthTestCase, SlackTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_subscribe.py b/breathecode/authenticate/tests/urls/v1/tests_subscribe.py similarity index 100% rename from breathecode/authenticate/tests/urls/tests_subscribe.py rename to breathecode/authenticate/tests/urls/v1/tests_subscribe.py diff --git a/breathecode/authenticate/tests/urls/tests_token_me.py b/breathecode/authenticate/tests/urls/v1/tests_token_me.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_token_me.py rename to breathecode/authenticate/tests/urls/v1/tests_token_me.py index 33a494b73..1742a2e9e 100644 --- a/breathecode/authenticate/tests/urls/tests_token_me.py +++ b/breathecode/authenticate/tests/urls/v1/tests_token_me.py @@ -11,7 +11,7 @@ from breathecode.tests.mixins.breathecode_mixin.breathecode import fake -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase UTC_NOW = timezone.now() TOKEN = fake.name() diff --git a/breathecode/authenticate/tests/urls/tests_user.py b/breathecode/authenticate/tests/urls/v1/tests_user.py similarity index 97% rename from breathecode/authenticate/tests/urls/tests_user.py rename to breathecode/authenticate/tests/urls/v1/tests_user.py index 1a149bfbf..936f1871e 100644 --- a/breathecode/authenticate/tests/urls/tests_user.py +++ b/breathecode/authenticate/tests/urls/v1/tests_user.py @@ -4,7 +4,8 @@ from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins import AuthTestCase + +from ...mixins import AuthTestCase class AuthenticateTestSuite(AuthTestCase): diff --git a/breathecode/authenticate/tests/urls/tests_user_me.py b/breathecode/authenticate/tests/urls/v1/tests_user_me.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_user_me.py rename to breathecode/authenticate/tests/urls/v1/tests_user_me.py index 047d28452..6632fd990 100644 --- a/breathecode/authenticate/tests/urls/tests_user_me.py +++ b/breathecode/authenticate/tests/urls/v1/tests_user_me.py @@ -2,13 +2,10 @@ Test cases for /user """ -import datetime - -import pytz from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def get_permission_serializer(permission): diff --git a/breathecode/authenticate/tests/urls/tests_user_me_invite.py b/breathecode/authenticate/tests/urls/v1/tests_user_me_invite.py similarity index 99% rename from breathecode/authenticate/tests/urls/tests_user_me_invite.py rename to breathecode/authenticate/tests/urls/v1/tests_user_me_invite.py index c2de2568b..6fc66fa50 100644 --- a/breathecode/authenticate/tests/urls/tests_user_me_invite.py +++ b/breathecode/authenticate/tests/urls/v1/tests_user_me_invite.py @@ -9,7 +9,7 @@ from rest_framework import status from rest_framework.response import Response -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def view_method_mock(request, *args, **kwargs): diff --git a/breathecode/authenticate/tests/urls/tests_user_me_invite_status.py b/breathecode/authenticate/tests/urls/v1/tests_user_me_invite_status.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_user_me_invite_status.py rename to breathecode/authenticate/tests/urls/v1/tests_user_me_invite_status.py index dcc7e3e99..f93af523d 100644 --- a/breathecode/authenticate/tests/urls/tests_user_me_invite_status.py +++ b/breathecode/authenticate/tests/urls/v1/tests_user_me_invite_status.py @@ -2,14 +2,13 @@ Set of tests for MeInviteView, this include duck tests """ -from random import choice -from unittest.mock import MagicMock, PropertyMock, patch +from unittest.mock import MagicMock, patch from django.urls.base import reverse_lazy from rest_framework import status from rest_framework.response import Response -from ..mixins.new_auth_test_case import AuthTestCase +from ...mixins.new_auth_test_case import AuthTestCase def view_method_mock(request, *args, **kwargs): diff --git a/breathecode/authenticate/tests/urls/tests_user_profile.py b/breathecode/authenticate/tests/urls/v1/tests_user_profile.py similarity index 98% rename from breathecode/authenticate/tests/urls/tests_user_profile.py rename to breathecode/authenticate/tests/urls/v1/tests_user_profile.py index 5e8d5df59..5a3c7f4c1 100644 --- a/breathecode/authenticate/tests/urls/tests_user_profile.py +++ b/breathecode/authenticate/tests/urls/v1/tests_user_profile.py @@ -2,10 +2,10 @@ Test cases for /profile/ """ -import pytz, datetime from django.urls.base import reverse_lazy from rest_framework import status -from ..mixins.new_auth_test_case import AuthTestCase + +from ...mixins.new_auth_test_case import AuthTestCase def get_serializer(self, profile, data={}): diff --git a/breathecode/authenticate/tests/permissions/__init__.py b/breathecode/authenticate/tests/urls/v2/__init__.py similarity index 100% rename from breathecode/authenticate/tests/permissions/__init__.py rename to breathecode/authenticate/tests/urls/v2/__init__.py diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_academy.py b/breathecode/authenticate/tests/urls/v2/tests_app_academy.py new file mode 100644 index 000000000..e273565e3 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_academy.py @@ -0,0 +1,79 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppAcademySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppAcademySerializer, "filter", m) + + yield obj + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_academy") + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_academy") + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_academy") + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_academy_id.py b/breathecode/authenticate/tests/urls/v2/tests_app_academy_id.py new file mode 100644 index 000000000..882322374 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_academy_id.py @@ -0,0 +1,82 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppAcademySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppAcademySerializer, "get", m) + + yield { + **obj, + "id": 1, + } + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_academy_id", kwargs={"academy_id": 1}) + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_academy_id", kwargs={"academy_id": 1}) + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_academy_id", kwargs={"academy_id": 1}) + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_city.py b/breathecode/authenticate/tests/urls/v2/tests_app_city.py new file mode 100644 index 000000000..e4bf4ee01 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_city.py @@ -0,0 +1,79 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppCitySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppCitySerializer, "filter", m) + + yield obj + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_city") + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_city") + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_city") + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_city_id.py b/breathecode/authenticate/tests/urls/v2/tests_app_city_id.py new file mode 100644 index 000000000..14b86cd60 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_city_id.py @@ -0,0 +1,82 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppCitySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppCitySerializer, "get", m) + + yield { + **obj, + "id": 1, + } + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_city_id", kwargs={"city_id": 1}) + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_city_id", kwargs={"city_id": 1}) + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_city_id", kwargs={"city_id": 1}) + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_country.py b/breathecode/authenticate/tests/urls/v2/tests_app_country.py new file mode 100644 index 000000000..579392722 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_country.py @@ -0,0 +1,79 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppCountrySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppCountrySerializer, "filter", m) + + yield obj + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_country") + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_country") + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_country") + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_country_id.py b/breathecode/authenticate/tests/urls/v2/tests_app_country_id.py new file mode 100644 index 000000000..21f742832 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_country_id.py @@ -0,0 +1,82 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppCountrySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppCountrySerializer, "get", m) + + yield { + **obj, + "code": 1, + } + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_country_id", kwargs={"country_id": 1}) + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_country_id", kwargs={"country_id": 1}) + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_country_id", kwargs={"country_id": 1}) + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_student.py b/breathecode/authenticate/tests/urls/v2/tests_app_student.py new file mode 100644 index 000000000..b6d6c2e65 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_student.py @@ -0,0 +1,82 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppProfileAcademySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppProfileAcademySerializer, "filter", m) + + yield { + **obj, + "role__slug": "student", + } + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_student") + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_student") + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_student") + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_student_id.py b/breathecode/authenticate/tests/urls/v2/tests_app_student_id.py new file mode 100644 index 000000000..1eb30043e --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_student_id.py @@ -0,0 +1,124 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppProfileAcademySerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppProfileAcademySerializer, "get", m) + + yield { + **obj, + "role__slug": "student", + } + + +@pytest.fixture +def numeric_expected(expected): + yield { + **expected, + "id": 1, + } + + +@pytest.fixture +def non_numeric_expected(expected): + yield { + **expected, + "email": "a", + } + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_student_id", kwargs={"user_id_or_email": 1}) + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_student_id", kwargs={"user_id_or_email": 1}) + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + numeric_expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_student_id", kwargs={"user_id_or_email": 1}) + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == numeric_expected + assert response.status_code == status.HTTP_200_OK + + +def test_location_url_( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + non_numeric_expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_student_id", kwargs={"user_id_or_email": "a"}) + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == non_numeric_expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_user.py b/breathecode/authenticate/tests/urls/v2/tests_app_user.py new file mode 100644 index 000000000..22c326288 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_user.py @@ -0,0 +1,79 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppUserSerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppUserSerializer, "filter", m) + + yield obj + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_user") + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_user") + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_user") + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/urls/v2/tests_app_user_id.py b/breathecode/authenticate/tests/urls/v2/tests_app_user_id.py new file mode 100644 index 000000000..50b5cffbf --- /dev/null +++ b/breathecode/authenticate/tests/urls/v2/tests_app_user_id.py @@ -0,0 +1,82 @@ +from typing import Any, Callable + +import capyc.pytest as capy +import linked_services.pytest as linked_services +import pytest +from django.http import JsonResponse +from django.urls import reverse_lazy +from rest_framework import status + +from breathecode.authenticate.serializers import CapyAppUserSerializer + + +@pytest.fixture(autouse=True) +def setup(db): + yield + + +@pytest.fixture +def expected(monkeypatch: pytest.MonkeyPatch, fake: capy.Fake): + obj = { + "slug": fake.slug(), + "name": fake.name(), + "description": fake.text(), + } + + def m(self, **kwargs): + return JsonResponse({**obj, **kwargs}, status=200) + + monkeypatch.setattr(CapyAppUserSerializer, "get", m) + + yield { + **obj, + "id": 1, + } + + +def test_no_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_user_id", kwargs={"user_id": 1}) + response = client.get(url) + + json = response.json() + expected = {"detail": "no-authorization-header", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_invalid_authorization_header(client: capy.Client): + url = reverse_lazy("v2:authenticate:app_user_id", kwargs={"user_id": 1}) + response = client.get(url, headers={"Authorization": "Bearer 1234"}) + + json = response.json() + expected = {"detail": "unknown-auth-schema", "status_code": 401} + + assert json == expected + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +def test_location_url( + database: capy.Database, + client: capy.Client, + service: linked_services.Service, + get_app_signature: Callable[[Any], dict[str, Any]], + expected: dict[str, str], +): + url = reverse_lazy("v2:authenticate:app_user_id", kwargs={"user_id": 1}) + + model = database.create( + app={ + "require_an_agreement": False, + "slug": "rigobot", + **get_app_signature(), + }, + ) + + service.sign_jwt(client, model.app) + response = client.get(url) + + json = response.json() + + assert json == expected + assert response.status_code == status.HTTP_200_OK diff --git a/breathecode/authenticate/tests/permissions/contexts/__init__.py b/breathecode/authenticate/urls/__init__.py similarity index 100% rename from breathecode/authenticate/tests/permissions/contexts/__init__.py rename to breathecode/authenticate/urls/__init__.py diff --git a/breathecode/authenticate/urls.py b/breathecode/authenticate/urls/v1.py similarity index 97% rename from breathecode/authenticate/urls.py rename to breathecode/authenticate/urls/v1.py index 0a024578f..b91ee2347 100644 --- a/breathecode/authenticate/urls.py +++ b/breathecode/authenticate/urls/v1.py @@ -21,7 +21,7 @@ from breathecode.authenticate.actions import get_user_language -from .views import ( +from ..views import ( AcademyAuthSettingsView, AcademyGithubSyncView, AcademyInviteView, @@ -113,6 +113,8 @@ path("academy//member", MemberView.as_view(), name="academy_id_member"), path("academy//member/", MemberView.as_view(), name="academy_id_member_id"), path("academy/member/", MemberView.as_view(), name="academy_member_id"), + path("app/student", StudentView.as_view(), name="app_student"), + path("app/student/", StudentView.as_view(), name="app_student_id"), path("academy/student", StudentView.as_view(), name="academy_student"), path("academy/student/", StudentView.as_view(), name="academy_student_id"), # TODO: these endpoints starts with academy but actually they are related to the user, not to the academy diff --git a/breathecode/authenticate/urls/v2.py b/breathecode/authenticate/urls/v2.py new file mode 100644 index 000000000..104acd178 --- /dev/null +++ b/breathecode/authenticate/urls/v2.py @@ -0,0 +1,24 @@ +from django.urls import path + +from ..views import V2AppAcademyView, V2AppCityView, V2AppCountryView, V2AppStudentView, V2AppUserView +from .v1 import urlpatterns as urlpatterns_v1 + +deprecation_list = [ + "app/user", + "app/user/", +] + +app_name = "authenticate" +urlpatterns = [ + path("app/user", V2AppUserView.as_view(), name="app_user"), + path("app/user/", V2AppUserView.as_view(), name="app_user_id"), + path("app/student", V2AppStudentView.as_view(), name="app_student"), + path("app/student/", V2AppStudentView.as_view(), name="app_student_id"), + path("app/academy", V2AppAcademyView.as_view(), name="app_academy"), + path("app/academy/", V2AppAcademyView.as_view(), name="app_academy_id"), + path("app/city", V2AppCityView.as_view(), name="app_city"), + path("app/city/", V2AppCityView.as_view(), name="app_city_id"), + path("app/country", V2AppCountryView.as_view(), name="app_country"), + path("app/country/", V2AppCountryView.as_view(), name="app_country_id"), + *[r for r in urlpatterns_v1 if r.pattern._route not in deprecation_list], +] diff --git a/breathecode/authenticate/views.py b/breathecode/authenticate/views.py index 3419382c9..5c3213a6b 100644 --- a/breathecode/authenticate/views.py +++ b/breathecode/authenticate/views.py @@ -6,6 +6,7 @@ import re import urllib.parse from datetime import timedelta +from typing import Any from urllib.parse import parse_qs, urlencode, urlparse import aiohttp @@ -97,6 +98,11 @@ AppUserSerializer, AuthSerializer, AuthSettingsBigSerializer, + CapyAppAcademySerializer, + CapyAppCitySerializer, + CapyAppCountrySerializer, + CapyAppProfileAcademySerializer, + CapyAppUserSerializer, GetGitpodUserSerializer, GetProfileAcademySerializer, GetProfileAcademySmallSerializer, @@ -761,6 +767,69 @@ def put(self, request, invite_id=None, profileacademy_id=None, academy_id=None): return Response(serializer.data) +class V2AppUserView(APIView): + permission_classes = [AllowAny] + + @scope(["read:user"]) + def get(self, request: LinkedHttpRequest, app: LinkedApp, token: LinkedToken, user_id: int | None = None): + serializer = CapyAppUserSerializer(request) + if user_id: + return serializer.get(id=user_id) + + return serializer.filter() + + +class V2AppStudentView(APIView): + permission_classes = [AllowAny] + + @scope(["read:student"]) + def get(self, request: LinkedHttpRequest, app: LinkedApp, token: LinkedToken, user_id_or_email: str | None = None): + serializer = CapyAppProfileAcademySerializer(request) + if user_id_or_email: + if user_id_or_email.isnumeric(): + return serializer.get(id=int(user_id_or_email), role__slug="student") + else: + return serializer.get(email=user_id_or_email, role__slug="student") + + return serializer.filter(role__slug="student") + + +class V2AppAcademyView(APIView): + permission_classes = [AllowAny] + + @scope(["read:academy"]) + def get(self, request: LinkedHttpRequest, app: LinkedApp, token: LinkedToken, academy_id: int | None = None): + serializer = CapyAppAcademySerializer(request) + if academy_id: + return serializer.get(id=academy_id) + + return serializer.filter() + + +class V2AppCityView(APIView): + permission_classes = [AllowAny] + + @scope(["read:city"]) + def get(self, request: LinkedHttpRequest, app: LinkedApp, token: LinkedToken, city_id: int | None = None): + serializer = CapyAppCitySerializer(request) + if city_id: + return serializer.get(id=city_id) + + return serializer.filter() + + +class V2AppCountryView(APIView): + permission_classes = [AllowAny] + + @scope(["read:country"]) + def get(self, request: LinkedHttpRequest, app: LinkedApp, token: LinkedToken, country_id: int | None = None): + serializer = CapyAppCountrySerializer(request) + if country_id: + return serializer.get(code=country_id) + + return serializer.filter() + + class StudentView(APIView, GenerateLookupsMixin): extensions = APIViewExtensions(paginate=True, sort="-created_at") @@ -1049,7 +1118,12 @@ def get_github_token(request, token=None): @api_view(["GET"]) @permission_classes([AllowAny]) -def save_github_token(request): +async def save_github_token(request): + def error_message(obj: Any, default: str): + if isinstance(obj, dict): + return obj.get("error_description") or obj.get("error") or default + + return default logger.debug("Github callback just landed") logger.debug(request.query_params) @@ -1082,166 +1156,180 @@ def save_github_token(request): "code": code, } headers = {"Accept": "application/json"} - resp = requests.post("https://github.com/login/oauth/access_token", data=payload, headers=headers, timeout=2) - if resp.status_code == 200: - - logger.debug("Github responded with 200") - body = resp.json() - if "access_token" not in body: - raise APIException(body["error_description"]) + async with aiohttp.ClientSession() as session: + async with session.post( + "https://github.com/login/oauth/access_token", data=payload, headers=headers, timeout=30 + ) as resp: + body = await resp.json() + logger.debug(f"https://github.com/login/oauth/access_token => {body}") + if resp.status != 200: + raise APIException(f"Github code {resp.status}: {error_message(body, 'error getting github token')}") + + if "access_token" not in body: + raise APIException(f"Github code {resp.status}: {error_message(body, 'error getting github token')}") + + github_token = body["access_token"] + async with aiohttp.ClientSession() as session: + async with session.get( + "https://api.github.com/user", headers={"Authorization": "token " + github_token}, timeout=30 + ) as resp: + github_user = await resp.json() + logger.debug(f"https://api.github.com/user => {github_user}") + if resp.status != 200: + raise APIException( + f"Github code {resp.status}: {error_message(github_user, 'error getting github user')}" + ) + if github_user["email"] is None: github_token = body["access_token"] - resp = requests.get( - "https://api.github.com/user", headers={"Authorization": "token " + github_token}, timeout=2 - ) - if resp.status_code == 200: - github_user = resp.json() - logger.debug(github_user) - - if github_user["email"] is None: - resp = requests.get( - "https://api.github.com/user/emails", headers={"Authorization": "token " + github_token}, timeout=2 - ) - if resp.status_code == 200: - emails = resp.json() + async with aiohttp.ClientSession() as session: + async with session.get( + "https://api.github.com/user/emails", headers={"Authorization": "token " + github_token}, timeout=30 + ) as resp: + if resp.status == 200: + emails = await resp.json() + logger.debug(f"https://api.github.com/user/emails => {emails}") primary_emails = [x for x in emails if x["primary"] == True] if len(primary_emails) > 0: github_user["email"] = primary_emails[0]["email"] elif len(emails) > 0: github_user["email"] = emails[0]["email"] - if github_user["email"] is None: - raise ValidationError("Impossible to retrieve user email") - - user = None # assuming by default that its a new user - # is a valid token??? if not valid it will become None - if token is not None and token != "": - token = Token.get_valid(token) - if not token: - logger.debug("Token not found or is expired") - raise ValidationException( - "Token was not found or is expired, please use a different token", - code=404, - slug="token-not-found", - ) - user = User.objects.filter(auth_token=token.id).first() - else: - # for the token to become null for easier management - token = None - - # user can't be found thru token, lets try thru the github credentials - if token is None and user is None: - user = User.objects.filter(credentialsgithub__github_id=github_user["id"]).first() - if user is None: - user = User.objects.filter( - email__iexact=github_user["email"], credentialsgithub__isnull=True - ).first() - - user_does_not_exists = user is None - if user_does_not_exists: - invite = UserInvite.objects.filter(status="WAITING_LIST", email=github_user["email"]).first() - - if user_does_not_exists and invite: - if url is None or url == "": - url = get_app_url() - - return render_message( - request, - f"You are still number {invite.id} on the waiting list, we will email you once you are " - f'given access Back to 4Geeks.com', - academy=invite.academy, - ) + if github_user["email"] is None: + raise ValidationError("Impossible to retrieve user email") - if user_does_not_exists: - academy = None - if invite: - academy = invite.academy + user = None # assuming by default that its a new user + # is a valid token??? if not valid it will become None + if token is not None and token != "": + token = await Token.aget_valid(token) + if not token: + logger.debug("Token not found or is expired") + raise ValidationException( + "Token was not found or is expired, please use a different token", + code=404, + slug="token-not-found", + ) + user = await User.objects.filter(auth_token=token.id).afirst() + else: + # for the token to become null for easier management + token = None + + # user can't be found thru token, lets try thru the github credentials + if token is None and user is None: + user = await User.objects.filter(credentialsgithub__github_id=github_user["id"]).afirst() + if user is None: + user = await User.objects.filter( + email__iexact=github_user["email"], credentialsgithub__isnull=True + ).afirst() + + user_does_not_exists = user is None + if user_does_not_exists: + invite = await UserInvite.objects.filter(status="WAITING_LIST", email=github_user["email"]).afirst() + + if user_does_not_exists and invite: + if url is None or url == "": + url = get_app_url() - return render_message( - request, - "We could not find in our records the email associated to this github account, " - 'perhaps you want to signup to the platform first? Back to 4Geeks.com', - academy=academy, - ) + return render_message( + request, + f"You are still number {invite.id} on the waiting list, we will email you once you are " + f'given access Back to 4Geeks.com', + academy=invite.academy, + ) - github_credentials = CredentialsGithub.objects.filter(github_id=github_user["id"]).first() - - # update latest credentials if the user.id doesn't match - if github_credentials and github_credentials.user.id != user.id: - github_credentials.delete() - github_credentials = None - - # create a new credentials if it doesn't exists - if github_credentials is None: - github_credentials = CredentialsGithub(github_id=github_user["id"], user=user) - - github_credentials.token = github_token - github_credentials.username = github_user["login"] - github_credentials.email = github_user["email"].lower() - github_credentials.avatar_url = github_user["avatar_url"] - github_credentials.name = github_user["name"] - github_credentials.blog = github_user["blog"] - github_credentials.bio = github_user["bio"] - github_credentials.company = github_user["company"] - github_credentials.twitter_username = github_user["twitter_username"] - github_credentials.save() - - # IMPORTANT! The GithubAcademyUser.username is used for billing purposes on the provisioning activity, we have - # to keep it in sync when the user autenticate's with github - GithubAcademyUser.objects.filter(user=user).update(username=github_credentials.username) - - profile = Profile.objects.filter(user=user).first() - if profile is None: - profile = Profile( - user=user, - avatar_url=github_user["avatar_url"], - blog=github_user["blog"], - bio=github_user["bio"], - twitter_username=github_user["twitter_username"], - ) - profile.save() + if user_does_not_exists: + academy = None + if invite: + academy = invite.academy - if not profile.avatar_url: - profile.avatar_url = github_user["avatar_url"] - profile.save() + return render_message( + request, + "We could not find in our records the email associated to this github account, " + 'perhaps you want to signup to the platform first? Back to 4Geeks.com', + academy=academy, + ) - student_role = Role.objects.get(slug="student") - cus = CohortUser.objects.filter(user=user, role="STUDENT") - for cu in cus: - profile_academy = ProfileAcademy.objects.filter(user=cu.user, academy=cu.cohort.academy).first() - if profile_academy is None: - profile_academy = ProfileAcademy( - user=cu.user, - academy=cu.cohort.academy, - role=student_role, - email=cu.user.email, - first_name=cu.user.first_name, - last_name=cu.user.last_name, - status="ACTIVE", - ) - profile_academy.save() + github_credentials = ( + await CredentialsGithub.objects.filter(github_id=github_user["id"]).prefetch_related("user").afirst() + ) - if not token: - token, created = Token.get_or_create(user=user, token_type="login") + # update latest credentials if the user.id doesn't match + if github_credentials and github_credentials.user.id != user.id: + await github_credentials.adelete() + github_credentials = None + + # create a new credentials if it doesn't exists + if github_credentials is None: + github_credentials = CredentialsGithub(github_id=github_user["id"], user=user) + + github_credentials.token = github_token + github_credentials.username = github_user["login"] + github_credentials.email = github_user["email"].lower() + github_credentials.avatar_url = github_user["avatar_url"] + github_credentials.name = github_user["name"] + github_credentials.blog = github_user["blog"] + github_credentials.bio = github_user["bio"] + github_credentials.company = github_user["company"] + github_credentials.twitter_username = github_user["twitter_username"] + await github_credentials.asave() + + # IMPORTANT! The GithubAcademyUser.username is used for billing purposes on the provisioning activity, we have + # to keep it in sync when the user autenticate's with github + await GithubAcademyUser.objects.filter(user=user).aupdate(username=github_credentials.username) + + profile = await Profile.objects.filter(user=user).afirst() + if profile is None: + profile = Profile( + user=user, + avatar_url=github_user["avatar_url"], + blog=github_user["blog"], + bio=github_user["bio"], + twitter_username=github_user["twitter_username"], + ) + await profile.asave() + + if not profile.avatar_url: + profile.avatar_url = github_user["avatar_url"] + await profile.asave() - # register user in rigobot - rigobot_payload = {"organization": "4geeks", "user_token": token.key} - headers = {"Content-Type": "application/json"} - rigobot_resp = requests.post( - "https://rigobot.herokuapp.com/v1/auth/invite", timeout=2, headers=headers, json=rigobot_payload + student_role = await Role.objects.aget(slug="student") + cus = CohortUser.objects.filter(user=user, role="STUDENT").prefetch_related("cohort", "user", "cohort__academy") + async for cu in cus: + profile_academy = await ProfileAcademy.objects.filter(user=cu.user, academy=cu.cohort.academy).afirst() + if profile_academy is None: + profile_academy = ProfileAcademy( + user=cu.user, + academy=cu.cohort.academy, + role=student_role, + email=cu.user.email, + first_name=cu.user.first_name, + last_name=cu.user.last_name, + status="ACTIVE", ) + await profile_academy.asave() + + if not token: + token, _ = await Token.aget_or_create(user=user, token_type="login") + + # register user in rigobot + rigobot_payload = {"organization": "4geeks", "user_token": token.key} + headers = {"Content-Type": "application/json"} - if rigobot_resp.status_code == 200: + async with aiohttp.ClientSession() as session: + async with session.post( + "https://rigobot.herokuapp.com/v1/auth/invite", + headers={"Authorization": "token " + github_token}, + json=rigobot_payload, + timeout=30, + ) as resp: + if resp.status == 200: logger.debug("User registered on rigobot") else: logger.error("Failed user registration on rigobot") - redirect_url = set_query_parameter(url, "token", token.key) - return HttpResponseRedirect(redirect_to=redirect_url) - - else: - raise APIException("Error from github") + redirect_url = set_query_parameter(url, "token", token.key) + return HttpResponseRedirect(redirect_to=redirect_url) # Create your views here. diff --git a/breathecode/commons/tests/signals/tests_update_cache.py b/breathecode/commons/tests/signals/tests_update_cache.py index cbb88be07..abe6466ee 100644 --- a/breathecode/commons/tests/signals/tests_update_cache.py +++ b/breathecode/commons/tests/signals/tests_update_cache.py @@ -143,6 +143,7 @@ def test_model_cache__one_to_one(cache_cls, value): CohortCache, set( [ + admissions_models.Cohort, admissions_models.Academy, admissions_models.SyllabusVersion, admissions_models.SyllabusSchedule, @@ -195,6 +196,8 @@ def test_model_cache__many_to_one(cache_cls, value): CohortCache, set( [ + admissions_models.Cohort, + marketing_models.Course, payments_models.CohortSet, payments_models.PlanFinancing, payments_models.Subscription, diff --git a/breathecode/events/tests/actions/tests_update_or_create_event.py b/breathecode/events/tests/actions/tests_update_or_create_event.py index a95294a27..4ec233191 100644 --- a/breathecode/events/tests/actions/tests_update_or_create_event.py +++ b/breathecode/events/tests/actions/tests_update_or_create_event.py @@ -200,6 +200,7 @@ def test_update_or_create_event__with_academy(self): "asset_slug": None, "free_for_all": False, "uuid": uuid, + "is_public": True, } self.assertEqual(self.bc.database.list_of("events.Event"), [kwargs]) @@ -292,6 +293,7 @@ def test_update_or_create_event__with_event(self): "asset_slug": None, "free_for_all": False, "uuid": uuid, + "is_public": True, } self.assertEqual(self.bc.database.list_of("events.Event"), [kwargs]) diff --git a/breathecode/events/tests/permissions/contexts/tests_event.py b/breathecode/events/tests/permissions/contexts/tests_event.py deleted file mode 100644 index 77fd9fb3f..000000000 --- a/breathecode/events/tests/permissions/contexts/tests_event.py +++ /dev/null @@ -1,51 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from ....permissions.contexts import event -from ...mixins.new_events_tests_case import EventTestCase - -from breathecode.services import LaunchDarkly - - -def serializer(event): - author = f"{event.author.first_name} {event.author.last_name} ({event.author.email})" if event.author else "unknown" - return { - "id": event.id, - "slug": event.slug, - "lang": event.lang, - "academy": event.academy.slug if event.academy else "unknown", - "organization": event.organization.name if event.organization else "unknown", - "published_at": event.published_at, - "event_type": event.event_type.slug if event.event_type else "unknown", - } - - -value = random.randint(1, 1000) - - -class AcademyEventTestSuite(EventTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.context", MagicMock(return_value=value)) - def test_make_right_calls(self): - model = self.bc.database.create(event=1) - - ld = LaunchDarkly() - result = event(ld, model.event) - - self.assertEqual( - self.bc.database.list_of("events.Event"), - [ - self.bc.format.to_dict(model.event), - ], - ) - - contexts = serializer(model.event) - - self.assertEqual( - LaunchDarkly.context.call_args_list, - [ - call("1", model.event.title, "event", contexts), - ], - ) - - self.assertEqual(result, value) diff --git a/breathecode/events/tests/permissions/contexts/tests_event_type.py b/breathecode/events/tests/permissions/contexts/tests_event_type.py deleted file mode 100644 index 10ac6c4d4..000000000 --- a/breathecode/events/tests/permissions/contexts/tests_event_type.py +++ /dev/null @@ -1,48 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from ....permissions.contexts import event_type -from ...mixins.new_events_tests_case import EventTestCase - -from breathecode.services import LaunchDarkly - - -def serializer(event_type): - return { - "id": event_type.id, - "slug": event_type.slug, - "academy": event_type.academy.slug, - "lang": event_type.lang, - } - - -value = random.randint(1, 1000) - - -class AcademyEventTestSuite(EventTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.context", MagicMock(return_value=value)) - def test_make_right_calls(self): - kwargs = {"icon_url": self.bc.fake.url()} - model = self.bc.database.create(event_type=kwargs) - - ld = LaunchDarkly() - result = event_type(ld, model.event_type) - - self.assertEqual( - self.bc.database.list_of("events.EventType"), - [ - self.bc.format.to_dict(model.event_type), - ], - ) - - contexts = serializer(model.event_type) - - self.assertEqual( - LaunchDarkly.context.call_args_list, - [ - call("1", model.event_type.name, "event-type", contexts), - ], - ) - - self.assertEqual(result, value) diff --git a/breathecode/events/tests/permissions/flags/__init__.py b/breathecode/events/tests/permissions/flags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/breathecode/events/tests/permissions/flags/release/__init__.py b/breathecode/events/tests/permissions/flags/release/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/breathecode/events/tests/permissions/flags/release/tests_enable_consume_live_classes.py b/breathecode/events/tests/permissions/flags/release/tests_enable_consume_live_classes.py deleted file mode 100644 index 41c85e5ae..000000000 --- a/breathecode/events/tests/permissions/flags/release/tests_enable_consume_live_classes.py +++ /dev/null @@ -1,46 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from .....permissions.flags import api -from ....mixins.new_events_tests_case import EventTestCase -from breathecode.authenticate.permissions import contexts as authenticate_contexts -from breathecode.services import LaunchDarkly - -value = bool(random.randbytes(1)) - -context_value = random.randint(1, 100) - - -class AcademyEventTestSuite(EventTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.get", MagicMock(return_value=value)) - @patch("breathecode.authenticate.permissions.contexts.user", MagicMock(return_value=context_value)) - def test_make_right_calls(self): - model = self.bc.database.create(user=1) - - result = api.release.enable_consume_live_classes(model.user) - - self.assertEqual( - self.bc.database.list_of("auth.User"), - [ - self.bc.format.to_dict(model.user), - ], - ) - - self.assertEqual(len(authenticate_contexts.user.call_args_list), 1) - args, kwargs = authenticate_contexts.user.call_args_list[0] - - self.assertEqual(len(args), 2) - self.assertEqual(len(kwargs), 0) - - self.assertTrue(isinstance(args[0], LaunchDarkly)) - self.assertEqual(args[1], model.user) - - self.assertEqual(result, value) - - self.assertEqual( - LaunchDarkly.get.call_args_list, - [ - call("api.release.enable_consume_live_classes", context_value, False), - ], - ) diff --git a/breathecode/events/tests/permissions/flags/release/tests_enable_consume_live_events.py b/breathecode/events/tests/permissions/flags/release/tests_enable_consume_live_events.py deleted file mode 100644 index 0e792ce2b..000000000 --- a/breathecode/events/tests/permissions/flags/release/tests_enable_consume_live_events.py +++ /dev/null @@ -1,120 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from .....permissions.flags import api -from ....mixins.new_events_tests_case import EventTestCase -from breathecode.authenticate.permissions import contexts as authenticate_contexts -from breathecode.admissions.permissions import contexts as admissions_contexts -from breathecode.events.permissions import contexts -from breathecode.services import LaunchDarkly - -value = bool(random.randbytes(1)) -join_contexts_value = random.randint(1, 100) - -context1 = random.randint(1, 100) -context2 = random.randint(1, 100) -context3 = random.randint(1, 100) -context4 = random.randint(1, 100) - - -def assert_context_was_call(self, fn, model): - self.assertEqual(len(fn.call_args_list), 1) - args, kwargs = fn.call_args_list[0] - - self.assertEqual(len(args), 2) - self.assertEqual(len(kwargs), 0) - - self.assertTrue(isinstance(args[0], LaunchDarkly)) - self.assertEqual(args[1], model) - - -class AcademyEventTestSuite(EventTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.get", MagicMock(return_value=value)) - @patch( - "breathecode.services.launch_darkly.client.LaunchDarkly.join_contexts", - MagicMock(return_value=join_contexts_value), - ) - @patch("breathecode.authenticate.permissions.contexts.user", MagicMock(return_value=context1)) - @patch("breathecode.events.permissions.contexts.event", MagicMock(return_value=context2)) - @patch("breathecode.events.permissions.contexts.event_type", MagicMock(return_value=context3)) - @patch("breathecode.admissions.permissions.contexts.academy", MagicMock(return_value=context4)) - def test_make_right_calls__without_all_contexts(self): - model = self.bc.database.create(user=1, event=1) - - result = api.release.enable_consume_live_events(model.user, model.event) - - self.assertEqual( - self.bc.database.list_of("auth.User"), - [ - self.bc.format.to_dict(model.user), - ], - ) - - assert_context_was_call(self, authenticate_contexts.user, model.user) - # assert_context_call(self, admissions_contexts.academy, model.academy) - assert_context_was_call(self, contexts.event, model.event) - # assert_context_call(self, contexts.event_type, model.event_type) - - self.assertEqual(admissions_contexts.academy.call_args_list, []) - self.assertEqual(contexts.event_type.call_args_list, []) - - self.assertEqual(result, value) - - self.assertEqual( - LaunchDarkly.join_contexts.call_args_list, - [ - call(context1, context2), - ], - ) - - self.assertEqual( - LaunchDarkly.get.call_args_list, - [ - call("api.release.enable_consume_live_events", join_contexts_value, False), - ], - ) - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.get", MagicMock(return_value=value)) - @patch( - "breathecode.services.launch_darkly.client.LaunchDarkly.join_contexts", - MagicMock(return_value=join_contexts_value), - ) - @patch("breathecode.authenticate.permissions.contexts.user", MagicMock(return_value=context1)) - @patch("breathecode.events.permissions.contexts.event", MagicMock(return_value=context2)) - @patch("breathecode.events.permissions.contexts.event_type", MagicMock(return_value=context3)) - @patch("breathecode.admissions.permissions.contexts.academy", MagicMock(return_value=context4)) - def test_make_right_calls__with_all_contexts(self): - event_type = {"icon_url": self.bc.fake.url()} - model = self.bc.database.create(user=1, event=1, academy=1, event_type=event_type) - - result = api.release.enable_consume_live_events(model.user, model.event) - - self.assertEqual( - self.bc.database.list_of("auth.User"), - [ - self.bc.format.to_dict(model.user), - ], - ) - - assert_context_was_call(self, authenticate_contexts.user, model.user) - assert_context_was_call(self, admissions_contexts.academy, model.academy) - assert_context_was_call(self, contexts.event, model.event) - assert_context_was_call(self, contexts.event_type, model.event_type) - - self.assertEqual(result, value) - - self.assertEqual( - LaunchDarkly.join_contexts.call_args_list, - [ - call(context1, context2, context3, context4), - ], - ) - - self.assertEqual( - LaunchDarkly.get.call_args_list, - [ - call("api.release.enable_consume_live_events", join_contexts_value, False), - ], - ) diff --git a/breathecode/events/tests/urls/tests_all.py b/breathecode/events/tests/urls/tests_all.py index be805e75e..be40d126a 100644 --- a/breathecode/events/tests/urls/tests_all.py +++ b/breathecode/events/tests/urls/tests_all.py @@ -2,6 +2,7 @@ import capyc.pytest as capy from django.urls.base import reverse_lazy +from django.utils import timezone def serialize_event(event): @@ -9,14 +10,12 @@ def serialize_event(event): "id": event.id, "title": event.title, "starting_at": ( - event.starting_at.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" + event.starting_at.strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" if isinstance(event.starting_at, datetime) else None ), "ending_at": ( - event.ending_at.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" - if isinstance(event.ending_at, datetime) - else None + event.ending_at.strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" if isinstance(event.ending_at, datetime) else None ), "event_type": { "id": event.event_type.id, @@ -33,9 +32,7 @@ def serialize_event(event): "capacity": event.capacity, "status": event.status, "host": event.host, - "ended_at": ( - event.ended_at.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" if event.ended_at else None - ), + "ended_at": (event.ended_at.strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" if event.ended_at else None), "online_event": event.online_event, "is_public": event.is_public, "venue": ( @@ -119,8 +116,8 @@ def test_filter_by_technologies(client: capy.Client, database: capy.Database, fa "title": "My First Event", "capacity": 100, "banner": "https://example.com/banner.jpg", - "starting_at": datetime.now(), - "ending_at": datetime.now() + timedelta(hours=2), + "starting_at": timezone.now(), + "ending_at": timezone.now() + timedelta(hours=2), "status": "ACTIVE", "event_type_id": n + 1, } @@ -134,7 +131,6 @@ def test_filter_by_technologies(client: capy.Client, database: capy.Database, fa expected = [serialize_event(event) for event in model.event if "python" in event.event_type.technologies] assert response.status_code == 200 - assert len(json) == 1 assert expected == json @@ -175,8 +171,8 @@ def test_filter_by_technologies_obtain_two(client: capy.Client, database: capy.D "title": f"My Event {n + 1}", "capacity": 100, "banner": "https://example.com/banner.jpg", - "starting_at": datetime.now(), - "ending_at": datetime.now() + timedelta(hours=2), + "starting_at": timezone.now(), + "ending_at": timezone.now() + timedelta(hours=2), "status": "ACTIVE", "event_type_id": n + 1, } @@ -195,7 +191,6 @@ def test_filter_by_technologies_obtain_two(client: capy.Client, database: capy.D ] assert response.status_code == 200 - assert len(json) == 2 assert expected == json @@ -234,8 +229,8 @@ def test_all_academy_events_get_with_event_is_public_true_in_filter_is_public_tr "title": f"My Event {n + 1}", "capacity": 100, "banner": "https://example.com/banner.jpg", - "starting_at": datetime.now(), - "ending_at": datetime.now() + timedelta(hours=2), + "starting_at": timezone.now(), + "ending_at": timezone.now() + timedelta(hours=2), "status": "ACTIVE", "event_type_id": n + 1, "is_public": True, @@ -250,7 +245,6 @@ def test_all_academy_events_get_with_event_is_public_true_in_filter_is_public_tr expected = [serialize_event(event) for event in model.event if event.is_public] assert response.status_code == 200 - assert len(json) == len(expected) assert expected == json @@ -289,8 +283,8 @@ def test_all_academy_events_get_with_event_is_public_false_in_filter_is_public_t "title": f"My Event {n + 1}", "capacity": 100, "banner": "https://example.com/banner.jpg", - "starting_at": datetime.now(), - "ending_at": datetime.now() + timedelta(hours=2), + "starting_at": timezone.now(), + "ending_at": timezone.now() + timedelta(hours=2), "status": "ACTIVE", "event_type_id": n + 1, "is_public": False, @@ -305,7 +299,6 @@ def test_all_academy_events_get_with_event_is_public_false_in_filter_is_public_t expected = [serialize_event(event) for event in model.event if event.is_public] assert response.status_code == 200 - assert len(json) == len(expected) assert expected == json @@ -344,8 +337,8 @@ def test_all_academy_events_get_with_event_is_public_false_in_filter_is_public_f "title": f"My Event {n + 1}", "capacity": 100, "banner": "https://example.com/banner.jpg", - "starting_at": datetime.now(), - "ending_at": datetime.now() + timedelta(hours=2), + "starting_at": timezone.now(), + "ending_at": timezone.now() + timedelta(hours=2), "status": "ACTIVE", "event_type_id": n + 1, "is_public": False, @@ -360,7 +353,6 @@ def test_all_academy_events_get_with_event_is_public_false_in_filter_is_public_f expected = [serialize_event(event) for event in model.event if event.is_public == False] assert response.status_code == 200 - assert len(json) == len(expected) assert expected == json @@ -399,8 +391,8 @@ def test_all_academy_events_get_with_event_is_public_true_in_filter_is_public_fa "title": f"My Event {n + 1}", "capacity": 100, "banner": "https://example.com/banner.jpg", - "starting_at": datetime.now(), - "ending_at": datetime.now() + timedelta(hours=2), + "starting_at": timezone.now(), + "ending_at": timezone.now() + timedelta(hours=2), "status": "ACTIVE", "event_type_id": n + 1, "is_public": True, @@ -415,5 +407,4 @@ def test_all_academy_events_get_with_event_is_public_true_in_filter_is_public_fa expected = [serialize_event(event) for event in model.event if event.is_public == False] assert response.status_code == 200 - assert len(json) == len(expected) assert expected == json diff --git a/breathecode/events/tests/urls/tests_me_event_id_join.py b/breathecode/events/tests/urls/tests_me_event_id_join.py index 3f7248479..5cee1f68f 100644 --- a/breathecode/events/tests/urls/tests_me_event_id_join.py +++ b/breathecode/events/tests/urls/tests_me_event_id_join.py @@ -174,7 +174,6 @@ def test_no_consumables(self): # When: Feature flag set to False # Then: return 404 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=False)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -211,7 +210,6 @@ def test_no_consumables__bypass_with_feature_flag__live_event_not_found(self): # When: Feature flag set to False, right hash and event.live_stream_url not set # Then: return 400 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=False)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -269,7 +267,6 @@ def test_no_consumables__bypass_with_feature_flag__with_live_event__cohort_witho # When: Feature flag set to False, right hash and event.live_stream_url set # Then: return 302 to cohort.online_meeting_url and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=False)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -339,7 +336,6 @@ def test_no_consumables__bypass_with_feature_flag__with_live_event__cohort_with_ # When: Feature flag set to True # Then: return 404 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -376,7 +372,6 @@ def test_no_consumables__it_try_to_consume__live_event_not_found(self): # When: Feature flag set to True and event.live_stream_url not set # Then: return 400 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -434,7 +429,6 @@ def test_no_consumables__it_try_to_consume__with_live_event__cohort_without_url( # When: Feature flag set to True and event.live_stream_url set # Then: return 402 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -524,7 +518,6 @@ def test_no_consumables__it_try_to_consume__with_live_event__cohort_with_url(sel # When: Feature flag set to True, event end in the past and event.live_stream_url set # Then: return 200 and create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -600,7 +593,6 @@ def test_with_consumable__it_try_to_consume__with_live_event__in_the_past(self): # When: Feature flag set to True and event end in the future # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -708,7 +700,6 @@ def test_with_consumable__it_try_to_consume__with_live_event__in_the_future(self # -> academy.available_as_saas = True # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -820,7 +811,6 @@ def test_with_consumable__it_try_to_consume__with_live_event__in_the_future__aca # -> academy.available_as_saas = True # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -934,7 +924,6 @@ def test_with_consumable__it_try_to_consume__with_live_event__in_the_future__aca # -> cohort.available_as_saas = True # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1045,7 +1034,6 @@ def test_is_free_with_cohort_users_saas__cohort(self): # -> cohort.available_as_saas = None # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1155,7 +1143,6 @@ def test_is_free_with_cohort_users_saas__academy(self): # -> cohort.available_as_saas = False # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1250,7 +1237,6 @@ def test_is_free_with_cohort_users_no_saas__cohort(self): # -> cohort.available_as_saas = None # Then: return 200 and create a ConsumptionSession and create a EventCheckin with status DONE @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1341,7 +1327,6 @@ def test_is_free_with_cohort_users_no_saas__academy(self): # When: Feature flag set to True and event start and end in the future # Then: return 200 and create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1442,7 +1427,6 @@ def test_with_consumable__it_try_to_consume__with_live_event__in_the_future__sho # -> authenticate user is event host # Then: return 200 and avoid to create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1552,7 +1536,6 @@ def test_with_consumable__it_try_to_consume__with_live_event__in_the_future__sho ], ) @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) -@patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -1639,7 +1622,6 @@ def test__post__auth__no_saas__finantial_status_no_late( ], ) @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) -@patch("breathecode.events.permissions.flags.Release.enable_consume_live_events", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) diff --git a/breathecode/events/tests/urls/tests_me_event_liveclass_join_hash.py b/breathecode/events/tests/urls/tests_me_event_liveclass_join_hash.py index b8279b951..4c3d817b9 100644 --- a/breathecode/events/tests/urls/tests_me_event_liveclass_join_hash.py +++ b/breathecode/events/tests/urls/tests_me_event_liveclass_join_hash.py @@ -149,7 +149,6 @@ def test_no_consumables(self): # When: Feature flag set to False # Then: return 404 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=False)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -185,7 +184,6 @@ def test_no_consumables__bypass_with_feature_flag__live_class_not_found(self): # When: Feature flag set to False, right hash and cohort.live_class_join not set # Then: return 400 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=False)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -231,7 +229,6 @@ def test_no_consumables__bypass_with_feature_flag__with_live_class__cohort_witho # When: Feature flag set to False, right hash and cohort.live_class_join set # Then: return 302 to cohort.online_meeting_url @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=False)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -282,7 +279,6 @@ def test_no_consumables__bypass_with_feature_flag__with_live_class__cohort_with_ # When: Feature flag set to True # Then: return 404 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -318,7 +314,6 @@ def test_no_consumables__it_try_to_consume__live_class_not_found(self): # When: Feature flag set to True and cohort.live_class_join not set # Then: return 400 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -366,7 +361,6 @@ def test_no_consumables__it_try_to_consume__with_live_class__cohort_without_url( # When: Feature flag set to True and cohort.live_class_join set # Then: return 402 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -420,7 +414,6 @@ def test_no_consumables__it_try_to_consume__with_live_class__cohort_with_url(sel # When: Feature flag set to True, class end in the past and cohort.live_class_join set # Then: return 200 and create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -476,7 +469,6 @@ def test_with_consumable__it_try_to_consume__with_live_class__in_the_past(self): # When: Feature flag set to True and class end in the future # Then: return 200 and create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -565,7 +557,6 @@ def test_with_consumable__it_try_to_consume__with_live_class__in_the_future(self # When: Feature flag set to True and class start and end in the future # Then: return 200 and create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -654,7 +645,6 @@ def test_with_consumable__it_try_to_consume__with_live_class__in_the_future__sho # When: Feature flag set to True and class start and end in the future # Then: return 200 and create a ConsumptionSession @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) @@ -734,7 +724,6 @@ def test_with_consumable__it_try_to_consume__with_live_class__on_starting_time(s # When: Feature flag set to True and class start and end in the future # Then: return a redirection status 302 @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) - @patch("breathecode.events.permissions.flags.Release.enable_consume_live_classes", MagicMock(return_value=True)) @patch("django.db.models.signals.pre_delete.send_robust", MagicMock(return_value=None)) @patch("breathecode.admissions.signals.student_edu_status_updated.send_robust", MagicMock(return_value=None)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) diff --git a/breathecode/feedback/tasks.py b/breathecode/feedback/tasks.py index d3b6b27a5..14526b533 100644 --- a/breathecode/feedback/tasks.py +++ b/breathecode/feedback/tasks.py @@ -1,6 +1,7 @@ import os from datetime import timedelta +from capyc.rest_framework.exceptions import ValidationException from django.contrib.auth.models import User from django.core.cache import cache from django.utils import timezone @@ -15,7 +16,6 @@ from breathecode.notify import actions as notify_actions from breathecode.utils import TaskPriority, getLogger from breathecode.utils.redis import Lock -from capyc.rest_framework.exceptions import ValidationException from . import actions from .models import Answer, Survey @@ -27,7 +27,7 @@ ADMIN_URL = os.getenv("ADMIN_URL", "") API_URL = os.getenv("API_URL", "") ENV = os.getenv("ENV", "") -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False def build_question(answer): diff --git a/breathecode/feedback/tests/actions/tests_send_question.py b/breathecode/feedback/tests/actions/tests_send_question.py index 32acc95b0..be7645a03 100644 --- a/breathecode/feedback/tests/actions/tests_send_question.py +++ b/breathecode/feedback/tests/actions/tests_send_question.py @@ -552,7 +552,7 @@ def test_send_question__with_cohort_lang_es(self): "score": None, "status": "SENT", "survey_id": None, - "title": f"¿Cómo ha sido tu experiencia estudiando {certificate}?", + "title": f"¿Cómo ha sido tu experiencia estudiando {certificate} hasta este momento?", "token_id": n + 1, "user_id": n + 1, "question_by_slug": None, diff --git a/breathecode/feedback/tests/tasks/tests_generate_user_cohort_survey_answers.py b/breathecode/feedback/tests/tasks/tests_generate_user_cohort_survey_answers.py index 8e5562341..569b7528a 100644 --- a/breathecode/feedback/tests/tasks/tests_generate_user_cohort_survey_answers.py +++ b/breathecode/feedback/tests/tasks/tests_generate_user_cohort_survey_answers.py @@ -4,10 +4,10 @@ from unittest.mock import MagicMock, patch +from capyc.rest_framework.exceptions import ValidationException from django.utils import timezone from breathecode.feedback.tasks import generate_user_cohort_survey_answers -from capyc.rest_framework.exceptions import ValidationException from ..mixins import FeedbackTestCase @@ -108,7 +108,7 @@ def test_when_teacher_is_assigned(self): "academy_id": n + 1, }, { - "title": f"How has been your experience with the platform and content?", + "title": f"How has been your experience with the platform and content so far?", "lowest": "not good", "highest": "very good", "cohort_id": None, @@ -178,7 +178,7 @@ def test_when_cohort_has_syllabus(self): "cohort_id": None, }, { - "title": f"How has been your experience with the platform and content?", + "title": f"How has been your experience with the platform and content so far?", "lowest": "not good", "highest": "very good", "cohort_id": None, @@ -236,7 +236,7 @@ def test_when_cohort_is_available_as_saas(self): "cohort_id": None, }, { - "title": f"How has been your experience with the platform and content?", + "title": f"How has been your experience with the platform and content so far?", "lowest": "not good", "highest": "very good", "cohort_id": None, @@ -317,7 +317,7 @@ def test_role_assistant(self): "academy_id": n + 1, }, { - "title": f"How has been your experience with the platform and content?", + "title": f"How has been your experience with the platform and content so far?", "lowest": "not good", "highest": "very good", "cohort_id": None, diff --git a/breathecode/feedback/tests/tasks/tests_send_cohort_survey.py b/breathecode/feedback/tests/tasks/tests_send_cohort_survey.py index 80132da0c..c6c43a9b8 100644 --- a/breathecode/feedback/tests/tasks/tests_send_cohort_survey.py +++ b/breathecode/feedback/tests/tasks/tests_send_cohort_survey.py @@ -163,23 +163,20 @@ def test_when_student_not_found(self): tasks.generate_user_cohort_survey_answers.call_args_list, [call(model.user, model.survey, status="SENT")] ) token = self.bc.database.get("authenticate.Token", 1, dict=False) - self.assertEqual( - actions.send_email_message.call_args_list, - [ - call( - "nps_survey", - model.user.email, - { - "SUBJECT": "We need your feedback", - "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", - "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", - "BUTTON": "Answer the question", - "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", - }, - academy=model.academy, - ) - ], - ) + assert actions.send_email_message.call_args_list == [ + call( + "nps_survey", + model.user.email, + { + "SUBJECT": "How has been your experience at 4Geeks so far?", + "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", + "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", + "BUTTON": "Answer the question", + "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", + }, + academy=model.academy, + ) + ] @patch("os.getenv", MagicMock(side_effect=apply_get_env({"API_URL": "https://hello.com"}))) @patch("breathecode.feedback.tasks.generate_user_cohort_survey_answers", MagicMock()) @@ -211,23 +208,20 @@ def test_when_an_email_is_sent(self): [call(model.user, model.survey, status="SENT")], ) token = self.bc.database.get("authenticate.Token", model.survey.id, dict=False) - self.assertEqual( - actions.send_email_message.call_args_list, - [ - call( - "nps_survey", - model.user.email, - { - "SUBJECT": "We need your feedback", - "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", - "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", - "BUTTON": "Answer the question", - "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", - }, - academy=model.academy, - ) - ], - ) + assert actions.send_email_message.call_args_list == [ + call( + "nps_survey", + model.user.email, + { + "SUBJECT": "How has been your experience at 4Geeks so far?", + "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", + "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", + "BUTTON": "Answer the question", + "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", + }, + academy=model.academy, + ) + ] logging.Logger.info.call_args_list = [] logging.Logger.error.call_args_list = [] @@ -270,43 +264,35 @@ def test_when_an_email_is_sent_with_slack_team_and_user(self): token = self.bc.database.get("authenticate.Token", model.survey.id, dict=False) - self.assertEqual( - str(actions.send_slack.call_args_list), - str( - [ - call( - "nps_survey", - model.slack_user, - model.slack_team, - data={ - "SUBJECT": "We need your feedback", - "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", - "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", - "BUTTON": "Answer the question", - "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", - }, - academy=model.academy, - ) - ] - ), - ) - self.assertEqual( - actions.send_email_message.call_args_list, - [ - call( - "nps_survey", - model.user.email, - { - "SUBJECT": "We need your feedback", - "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", - "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", - "BUTTON": "Answer the question", - "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", - }, - academy=model.academy, - ) - ], - ) + assert actions.send_slack.call_args_list == [ + call( + "nps_survey", + model.slack_user, + model.slack_team, + data={ + "SUBJECT": "How has been your experience at 4Geeks so far?", + "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", + "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", + "BUTTON": "Answer the question", + "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", + }, + academy=model.academy, + ) + ] + assert actions.send_email_message.call_args_list == [ + call( + "nps_survey", + model.user.email, + { + "SUBJECT": "How has been your experience at 4Geeks so far?", + "MESSAGE": "Please take 5 minutes to give us feedback about your experience at the academy so far.", + "TRACKER_URL": f"https://hello.com/v1/feedback/survey/{model.survey.id}/tracker.png", + "BUTTON": "Answer the question", + "LINK": f"https://nps.4geeks.com/survey/{model.survey.id}?token={token.key}", + }, + academy=model.academy, + ) + ] logging.Logger.info.call_args_list = [] logging.Logger.error.call_args_list = [] diff --git a/breathecode/marketing/tests/urls/tests_course.py b/breathecode/marketing/tests/urls/tests_course.py index e76562015..58db8f2a0 100644 --- a/breathecode/marketing/tests/urls/tests_course.py +++ b/breathecode/marketing/tests/urls/tests_course.py @@ -25,6 +25,7 @@ def course_translation_serializer(course_translation): "title": course_translation.title, "landing_url": course_translation.landing_url, "video_url": course_translation.video_url, + "heading": course_translation.heading, } diff --git a/breathecode/marketing/tests/urls/tests_course_slug.py b/breathecode/marketing/tests/urls/tests_course_slug.py index 4052e207c..65a72aa9a 100644 --- a/breathecode/marketing/tests/urls/tests_course_slug.py +++ b/breathecode/marketing/tests/urls/tests_course_slug.py @@ -25,6 +25,7 @@ def course_translation_serializer(course_translation): "title": course_translation.title, "landing_url": course_translation.landing_url, "video_url": course_translation.video_url, + "heading": course_translation.heading, } diff --git a/breathecode/media/tasks.py b/breathecode/media/tasks.py index c7dc29bee..3ac29e057 100644 --- a/breathecode/media/tasks.py +++ b/breathecode/media/tasks.py @@ -14,7 +14,7 @@ from .utils import media_settings logger = logging.getLogger(__name__) -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False @task(bind=False, priority=TaskPriority.STUDENT.value) diff --git a/breathecode/mentorship/tests/permissions/contexts/__init__.py b/breathecode/mentorship/tests/permissions/contexts/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/breathecode/mentorship/tests/permissions/contexts/tests_mentorship_service.py b/breathecode/mentorship/tests/permissions/contexts/tests_mentorship_service.py deleted file mode 100644 index a078efef9..000000000 --- a/breathecode/mentorship/tests/permissions/contexts/tests_mentorship_service.py +++ /dev/null @@ -1,53 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from ....permissions.contexts import mentorship_service -from ...mixins import MentorshipTestCase - -from breathecode.services import LaunchDarkly - - -def serializer(mentorship_service): - return { - "id": mentorship_service.id, - "slug": mentorship_service.slug, - "max_duration": mentorship_service.max_duration, - "language": mentorship_service.language, - "academy": mentorship_service.academy.slug, - } - - -value = random.randint(1, 1000) - - -class AcademyEventTestSuite(MentorshipTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.context", MagicMock(return_value=value)) - def test_make_right_calls(self): - model = self.bc.database.create(mentorship_service=1) - - ld = LaunchDarkly() - result = mentorship_service(ld, model.mentorship_service) - - self.assertEqual( - self.bc.database.list_of("mentorship.MentorshipService"), - [ - self.bc.format.to_dict(model.mentorship_service), - ], - ) - - contexts = serializer(model.mentorship_service) - - self.assertEqual( - LaunchDarkly.context.call_args_list, - [ - call( - "1", - f"{model.mentorship_service.name} ({model.mentorship_service.slug})", - "mentoring-service", - contexts, - ), - ], - ) - - self.assertEqual(result, value) diff --git a/breathecode/mentorship/tests/permissions/flags/__init__.py b/breathecode/mentorship/tests/permissions/flags/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/breathecode/mentorship/tests/permissions/flags/release/__init__.py b/breathecode/mentorship/tests/permissions/flags/release/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/breathecode/mentorship/tests/permissions/flags/release/tests_enable_consume_mentorships.py b/breathecode/mentorship/tests/permissions/flags/release/tests_enable_consume_mentorships.py deleted file mode 100644 index 9fde4650c..000000000 --- a/breathecode/mentorship/tests/permissions/flags/release/tests_enable_consume_mentorships.py +++ /dev/null @@ -1,70 +0,0 @@ -import random -from unittest.mock import MagicMock, call, patch -from .....permissions.flags import api -from breathecode.authenticate.permissions import contexts as authenticate_contexts -from breathecode.admissions.permissions import contexts as admissions_contexts -from breathecode.mentorship.permissions import contexts -from breathecode.services import LaunchDarkly -from ....mixins import MentorshipTestCase - -value = bool(random.randbytes(1)) -join_contexts_value = random.randint(1, 100) - -context1 = random.randint(1, 100) -context2 = random.randint(1, 100) -context3 = random.randint(1, 100) - - -def assert_context_was_call(self, fn, model): - self.assertEqual(len(fn.call_args_list), 1) - args, kwargs = fn.call_args_list[0] - - self.assertEqual(len(args), 2) - self.assertEqual(len(kwargs), 0) - - self.assertTrue(isinstance(args[0], LaunchDarkly)) - self.assertEqual(args[1], model) - - -class AcademyEventTestSuite(MentorshipTestCase): - - @patch("ldclient.get", MagicMock()) - @patch("breathecode.services.launch_darkly.client.LaunchDarkly.get", MagicMock(return_value=value)) - @patch( - "breathecode.services.launch_darkly.client.LaunchDarkly.join_contexts", - MagicMock(return_value=join_contexts_value), - ) - @patch("breathecode.authenticate.permissions.contexts.user", MagicMock(return_value=context1)) - @patch("breathecode.mentorship.permissions.contexts.mentorship_service", MagicMock(return_value=context2)) - @patch("breathecode.admissions.permissions.contexts.academy", MagicMock(return_value=context3)) - def test_make_right_calls(self): - model = self.bc.database.create(user=1, mentorship_service=1) - - result = api.release.enable_consume_mentorships(model.user, model.mentorship_service) - - self.assertEqual( - self.bc.database.list_of("auth.User"), - [ - self.bc.format.to_dict(model.user), - ], - ) - - assert_context_was_call(self, authenticate_contexts.user, model.user) - assert_context_was_call(self, admissions_contexts.academy, model.academy) - assert_context_was_call(self, contexts.mentorship_service, model.mentorship_service) - - self.assertEqual(result, value) - - self.assertEqual( - LaunchDarkly.join_contexts.call_args_list, - [ - call(context1, context2, context3), - ], - ) - - self.assertEqual( - LaunchDarkly.get.call_args_list, - [ - call("api.release.enable_consume_mentorships", join_contexts_value, False), - ], - ) diff --git a/breathecode/mentorship/tests/urls/tests_academy_session.py b/breathecode/mentorship/tests/urls/tests_academy_session.py index d1a2027d4..0053dc2ab 100644 --- a/breathecode/mentorship/tests/urls/tests_academy_session.py +++ b/breathecode/mentorship/tests/urls/tests_academy_session.py @@ -92,6 +92,7 @@ def get_serializer(self, mentorship_session, mentor_profile, mentorship_service, "started_at": format_datetime(self, mentorship_session.started_at), "status": mentorship_session.status, "summary": mentorship_session.summary, + "rating": None, **data, } diff --git a/breathecode/mentorship/tests/urls_shortner/tests_meet_slug_service_slug.py b/breathecode/mentorship/tests/urls_shortner/tests_meet_slug_service_slug.py index d1ed9253c..bd03ffeb1 100644 --- a/breathecode/mentorship/tests/urls_shortner/tests_meet_slug_service_slug.py +++ b/breathecode/mentorship/tests/urls_shortner/tests_meet_slug_service_slug.py @@ -1781,91 +1781,6 @@ def test_error_inside_get_pending_sessions_or_create(self): self.bc.database.delete("auth.Permission") self.bc.database.delete("auth.User") - # TODO: disabled until have a new feature flags manager - # """ - # 🔽🔽🔽 GET without MentorProfile, good statuses with mentor urls, MentorshipSession without mentee - # passing session and mentee but mentee does not exist, user without name - # """ - - # @patch('breathecode.mentorship.actions.mentor_is_ready', MagicMock()) - # @patch('os.getenv', - # MagicMock(side_effect=apply_get_env({ - # 'DAILY_API_URL': URL, - # 'DAILY_API_KEY': API_KEY, - # }))) - # @patch('requests.request', - # apply_requests_request_mock([(201, f'{URL}/v1/rooms', { - # 'name': ROOM_NAME, - # 'url': ROOM_URL, - # })])) - # @patch('breathecode.mentorship.permissions.flags.Release.enable_consume_mentorships', - # MagicMock(return_value=False)) - # def test_with_mentor_profile__academy_available_as_saas__flag_eq_false__mentee(self): - # cases = [{ - # 'status': x, - # 'online_meeting_url': self.bc.fake.url(), - # 'booking_url': self.bc.fake.url(), - # } for x in ['ACTIVE', 'UNLISTED']] - # service= {'slug': 'join_mentorship'} - - # id = 0 - # for mentor_profile in cases: - # id += 1 - - # user = {'first_name': '', 'last_name': ''} - # base = self.bc.database.create(user=user, token=1, service=service) - - # mentorship_session = {'mentee_id': None} - # academy = {'available_as_saas': True} - # model = self.bc.database.create(mentor_profile=mentor_profile, - # mentorship_session=mentorship_session, - # user=user, - # mentorship_service={'language': 'en', 'video_provider': 'DAILY'}, - # academy=academy) - - # model.mentorship_session.mentee = None - # model.mentorship_session.save() - - # querystring = self.bc.format.to_querystring({ - # 'token': base.token.key, - # }) - # url = reverse_lazy('mentorship_shortner:meet_slug_service_slug', - # kwargs={ - # 'mentor_slug': model.mentor_profile.slug, - # 'service_slug': model.mentorship_service.slug - # }) + f'?{querystring}' - # response = self.client.get(url) - - # content = self.bc.format.from_bytes(response.content) - # expected = render( - # f'Hello student, you are about to start a {model.mentorship_service.name} with a mentor.', - # model.mentor_profile, - # base.token, - # fix_logo=True, - # start_session=True) - - # # dump error in external files - # if content != expected: - # with open('content.html', 'w') as f: - # f.write(content) - - # with open('expected.html', 'w') as f: - # f.write(expected) - - # self.assertEqual(content, expected) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(self.bc.database.list_of('mentorship.MentorProfile'), [ - # self.bc.format.to_dict(model.mentor_profile), - # ]) - # self.assertEqual(self.bc.database.list_of('payments.Consumable'), []) - # self.assertEqual(self.bc.database.list_of('payments.ConsumptionSession'), []) - - # # teardown - # self.bc.database.delete('mentorship.MentorProfile') - # self.bc.database.delete('auth.Permission') - # self.bc.database.delete('auth.User') - # self.bc.database.delete('payments.Service') - @patch("breathecode.mentorship.actions.mentor_is_ready", MagicMock()) @patch( "os.getenv", @@ -1893,7 +1808,6 @@ def test_error_inside_get_pending_sessions_or_create(self): ] ), ) - @patch("breathecode.mentorship.permissions.flags.Release.enable_consume_mentorships", MagicMock(return_value=True)) def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__mentee_with_no_consumables(self): cases = [ { @@ -2000,7 +1914,6 @@ def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__mentee_wi ] ), ) - @patch("breathecode.mentorship.permissions.flags.Release.enable_consume_mentorships", MagicMock(return_value=True)) def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__mentee_with_no_consumables_with_subcription( self, ): @@ -2116,7 +2029,6 @@ def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__mentee_wi ] ), ) - @patch("breathecode.mentorship.permissions.flags.Release.enable_consume_mentorships", MagicMock(return_value=True)) @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) @patch("breathecode.payments.tasks.end_the_consumption_session.apply_async", MagicMock(return_value=None)) def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__mentee_with_consumables(self): @@ -2276,7 +2188,6 @@ def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__mentee_wi ] ), ) - @patch("breathecode.mentorship.permissions.flags.Release.enable_consume_mentorships", MagicMock(return_value=True)) @patch("django.utils.timezone.now", MagicMock(return_value=UTC_NOW)) def test_with_mentor_profile__academy_available_as_saas__flag_eq_true__bypass_mentor_consume(self): cases = [ @@ -3353,6 +3264,11 @@ def test_with_mentor_profile__redirect_to_session__saas__bypass_consumption_fals "is_consumption_session": False, "flags": {"bypass_consumption": False}, }, + kwargs={ + "token": model.token, + "mentor_profile": model.mentor_profile, + "mentorship_service": model.mentorship_service, + }, ) context2 = feature.context( context={ @@ -3366,6 +3282,11 @@ def test_with_mentor_profile__redirect_to_session__saas__bypass_consumption_fals "is_consumption_session": False, "flags": {"bypass_consumption": False}, }, + kwargs={ + "token": model.token, + "mentor_profile": model.mentor_profile, + "mentorship_service": model.mentorship_service, + }, user=base.user, ) assert calls == [ @@ -3523,6 +3444,11 @@ def test_with_mentor_profile__redirect_to_session__saas__bypass_consumption_true "is_consumption_session": False, "flags": {"bypass_consumption": False}, }, + kwargs={ + "token": model.token, + "mentor_profile": model.mentor_profile, + "mentorship_service": model.mentorship_service, + }, ) context2 = feature.context( context={ @@ -3536,6 +3462,11 @@ def test_with_mentor_profile__redirect_to_session__saas__bypass_consumption_true "is_consumption_session": False, "flags": {"bypass_consumption": False}, }, + kwargs={ + "token": model.token, + "mentor_profile": model.mentor_profile, + "mentorship_service": model.mentorship_service, + }, user=base.user, ) assert calls == [ diff --git a/breathecode/payments/serializers.py b/breathecode/payments/serializers.py index bcc3b3529..b5372d6e1 100644 --- a/breathecode/payments/serializers.py +++ b/breathecode/payments/serializers.py @@ -170,6 +170,7 @@ class GetPlanSerializer(GetPlanSmallSerializer): is_renewable = serpy.Field() has_waiting_list = serpy.Field() owner = GetAcademySmallSerializer(required=False, many=False) + id = serpy.Field() class GetPlanOfferTranslationSerializer(serpy.Serializer): diff --git a/breathecode/payments/tasks.py b/breathecode/payments/tasks.py index 08129c4b2..8b8484799 100644 --- a/breathecode/payments/tasks.py +++ b/breathecode/payments/tasks.py @@ -43,7 +43,7 @@ ) logger = logging.getLogger(__name__) -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False @task(bind=True, priority=TaskPriority.WEB_SERVICE_PAYMENT.value) diff --git a/breathecode/payments/tests/urls/tests_checking.py b/breathecode/payments/tests/urls/tests_checking.py index edc84910a..349b396ad 100644 --- a/breathecode/payments/tests/urls/tests_checking.py +++ b/breathecode/payments/tests/urls/tests_checking.py @@ -1707,9 +1707,10 @@ def test__with_bag__type_bag__passing_type_preview__items_found__plan_already_bo service_item = {"how_many": how_many1} subscription = { "valid_until": None, - "next_payment_at": UTC_NOW + timedelta(seconds=1), - "status": random.choice(["CANCELLED", "DEPRECATED"]), + "next_payment_at": UTC_NOW + timedelta(seconds=1, days=2), + "status": random.choice(["FREE_TRIAL", "ACTIVE", "PAYMENT_ISSUE", "ERROR", "EXPIRED"]), } + academy = {"available_as_saas": True} model = self.bc.database.create( @@ -1816,7 +1817,7 @@ def test__with_bag__type_bag__passing_type_preview__items_found__plan_already_bo service_item = {"how_many": how_many1} subscription = { "valid_until": UTC_NOW + timedelta(seconds=1), - "status": random.choice(["CANCELLED", "ACTIVE", "DEPRECATED", "PAYMENT_ISSUE", "ERROR"]), + "status": random.choice(["ACTIVE", "PAYMENT_ISSUE", "ERROR"]), } academy = {"available_as_saas": True} diff --git a/breathecode/payments/tests/urls/tests_plan_slug.py b/breathecode/payments/tests/urls/tests_plan_slug.py index 43195ad1a..e47be43c2 100644 --- a/breathecode/payments/tests/urls/tests_plan_slug.py +++ b/breathecode/payments/tests/urls/tests_plan_slug.py @@ -3,9 +3,10 @@ from django.urls import reverse_lazy from rest_framework import status -from breathecode.utils.api_view_extensions.api_view_extension_handlers import APIViewExtensionHandlers +from breathecode.utils.api_view_extensions.api_view_extension_handlers import APIViewExtensionHandlers from breathecode.utils.api_view_extensions.extensions import lookup_extension + from ..mixins import PaymentsTestCase @@ -70,6 +71,7 @@ def get_serializer(event, currency, service=None, academy=None, service_items=[] "price_per_year": event.price_per_year, "service_items": service_items, "slug": event.slug, + "id": event.id, "status": event.status, "time_of_life": event.time_of_life, "time_of_life_unit": event.time_of_life_unit, diff --git a/breathecode/payments/tests/urls/tests_planoffer.py b/breathecode/payments/tests/urls/tests_planoffer.py index f6a6d3a2e..c76946b98 100644 --- a/breathecode/payments/tests/urls/tests_planoffer.py +++ b/breathecode/payments/tests/urls/tests_planoffer.py @@ -1,15 +1,15 @@ -from datetime import timedelta import math import random +from datetime import timedelta from unittest.mock import MagicMock, call, patch -from rest_framework.authtoken.models import Token from django.urls import reverse_lazy +from django.utils import timezone from rest_framework import status +from rest_framework.authtoken.models import Token from breathecode.payments import signals -from django.utils import timezone from ..mixins import PaymentsTestCase UTC_NOW = timezone.now() @@ -64,6 +64,7 @@ def plan_serializer(self, plan, service, currency, groups=[], permissions=[], se "currency": currency_serializer(currency), "slug": plan.slug, "status": plan.status, + "id": plan.id, "time_of_life": plan.time_of_life, "time_of_life_unit": plan.time_of_life_unit, "trial_duration": plan.trial_duration, diff --git a/breathecode/payments/views.py b/breathecode/payments/views.py index e7711db0e..36858d360 100644 --- a/breathecode/payments/views.py +++ b/breathecode/payments/views.py @@ -83,7 +83,7 @@ logger = getLogger(__name__) -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False class PlanView(APIView): diff --git a/breathecode/registry/migrations/0053_assettechnology_featured_course.py b/breathecode/registry/migrations/0053_assettechnology_featured_course.py new file mode 100644 index 000000000..a597a8123 --- /dev/null +++ b/breathecode/registry/migrations/0053_assettechnology_featured_course.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.2 on 2024-12-04 17:44 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("marketing", "0091_course_cohorts_order"), + ("registry", "0052_assettechnology_marketing_information"), + ] + + operations = [ + migrations.AddField( + model_name="assettechnology", + name="featured_course", + field=models.ForeignKey( + blank=True, + default=None, + help_text="The featured course for this technology", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="marketing.course", + ), + ), + ] diff --git a/breathecode/registry/migrations/0054_merge_20241216_1552.py b/breathecode/registry/migrations/0054_merge_20241216_1552.py new file mode 100644 index 000000000..4f2516fe7 --- /dev/null +++ b/breathecode/registry/migrations/0054_merge_20241216_1552.py @@ -0,0 +1,13 @@ +# Generated by Django 5.1.3 on 2024-12-16 15:52 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("registry", "0053_alter_asset_template_url"), + ("registry", "0053_assettechnology_featured_course"), + ] + + operations = [] diff --git a/breathecode/registry/models.py b/breathecode/registry/models.py index ef4ed4896..866a45f8d 100644 --- a/breathecode/registry/models.py +++ b/breathecode/registry/models.py @@ -60,6 +60,14 @@ class AssetTechnology(models.Model): default=False, help_text="If True, the technology will be programmatically deleted." ) featured_asset = models.ForeignKey("Asset", on_delete=models.SET_NULL, default=None, blank=True, null=True) + featured_course = models.ForeignKey( + "marketing.Course", + on_delete=models.SET_NULL, + null=True, + blank=True, + default=None, + help_text="The featured course for this technology", + ) visibility = models.CharField( max_length=20, choices=VISIBILITY, diff --git a/breathecode/registry/serializers.py b/breathecode/registry/serializers.py index f38ac11f1..8b0a1d6f1 100644 --- a/breathecode/registry/serializers.py +++ b/breathecode/registry/serializers.py @@ -8,6 +8,7 @@ from breathecode.admissions.models import Academy from breathecode.authenticate.models import ProfileAcademy +from breathecode.marketing.serializers import GetCourseSmallSerializer from breathecode.utils import serpy from .models import ( @@ -511,8 +512,15 @@ class AssetBigTechnologySerializer(AssetTechnologySerializer): assets = serpy.MethodField() alias = serpy.MethodField() sort_priority = serpy.Field() + featured_course = serpy.MethodField() marketing_information = serpy.Field() + def get_featured_course(self, obj): + if obj.featured_course: + obj.featured_course.lang = obj.lang or "en" + return GetCourseSmallSerializer(obj.featured_course).data + return None + def get_assets(self, obj): assets = Asset.objects.filter(technologies__id=obj.id) return list(map(lambda t: t.slug, assets)) diff --git a/breathecode/registry/tests/signals/tests_asset_saved.py b/breathecode/registry/tests/signals/tests_asset_saved.py index 9469aeeb0..9ac899f2e 100644 --- a/breathecode/registry/tests/signals/tests_asset_saved.py +++ b/breathecode/registry/tests/signals/tests_asset_saved.py @@ -481,7 +481,7 @@ class TestGitpodBranches: def msg1(self, asset: Asset): return ( f"This {asset.asset_type} can be opened both locally or with click and code (This " - "way you don't have to install nothing and it will open automatically on gitpod or github codespaces). " + "way you don't have to install anything and it will open automatically on gitpod or github codespaces). " ) def test_not_gitpod(self, database: capy.Database, signals: capy.Signals): @@ -536,7 +536,7 @@ def test_gitpod(self, database: capy.Database, signals: capy.Signals): class TestDurationBranches: def msg1(self, asset: Asset): - return f"This {asset.asset_type} will last {asset.duration}. " + return f"This {asset.asset_type} will last {asset.duration} hours. " @pytest.mark.parametrize("duration", [None, 0]) def test_not_duration(self, database: capy.Database, signals: capy.Signals, duration: Optional[int]): @@ -646,10 +646,10 @@ def test_difficulty(self, database: capy.Database, signals: capy.Signals): class TestReadmeBranches: def msg1(self, asset: Asset): - return f"The markdown file with the instructions of this {asset.asset_type} is the following: {asset.readme}." + return f"The markdown file with the instructions of this {asset.asset_type} is the following: {asset.html}." def msg2(self, asset: Asset): - return f"The markdown file with the content of this {asset.asset_type} is the following: {asset.readme}." + return f"The markdown file with the content of this {asset.asset_type} is the following: {asset.html}." @pytest.mark.parametrize("readme", [None, ""]) def test_not_readme(self, database: capy.Database, signals: capy.Signals, readme: Optional[str]): @@ -681,7 +681,7 @@ def test_readme__project(self, database: capy.Database, signals: capy.Signals, f signals.enable("breathecode.registry.signals.asset_saved") model = database.create( asset={ - "readme": fake.text(), + "html": fake.text(), "asset_type": "PROJECT", }, asset_category=1, @@ -707,7 +707,7 @@ def test_readme__anything_else(self, database: capy.Database, signals: capy.Sign signals.enable("breathecode.registry.signals.asset_saved") model = database.create( asset={ - "readme": fake.text(), + "html": fake.text(), "asset_type": random.choice(["LESSON", "EXERCISE", "QUIZ", "VIDEO", "ARTICLE"]), }, asset_category=1, diff --git a/breathecode/registry/tests/signals/tests_m2m_changed.py b/breathecode/registry/tests/signals/tests_m2m_changed.py index 84a99ab9a..1bcd17667 100644 --- a/breathecode/registry/tests/signals/tests_m2m_changed.py +++ b/breathecode/registry/tests/signals/tests_m2m_changed.py @@ -57,7 +57,7 @@ def msg1(self, asset: Asset): assets_related = ", ".join([x.slug for x in asset.assets_related.all()]) return ( f"In case you still need to learn more about the basics of this {asset.asset_type}, " - "you can check these lessons, exercises, " + "you can check these lessons, and exercises, " f"and related projects to get ready for this content: {assets_related}. " ) diff --git a/breathecode/registry/tests/urls/v1/tests_academy_technology.py b/breathecode/registry/tests/urls/v1/tests_academy_technology.py index b56b26239..a6c975123 100644 --- a/breathecode/registry/tests/urls/v1/tests_academy_technology.py +++ b/breathecode/registry/tests/urls/v1/tests_academy_technology.py @@ -39,6 +39,7 @@ def get_serializer(asset_technology, assets=[], asset_technologies=[], data={}): "title": asset_technology.title, "visibility": asset_technology.visibility, "sort_priority": asset_technology.sort_priority, + "featured_course": asset_technology.marketing_information, "marketing_information": asset_technology.marketing_information, **data, } diff --git a/breathecode/registry/tests/urls/v1/tests_technology.py b/breathecode/registry/tests/urls/v1/tests_technology.py index a730e96ed..ea175c8ed 100644 --- a/breathecode/registry/tests/urls/v1/tests_technology.py +++ b/breathecode/registry/tests/urls/v1/tests_technology.py @@ -30,6 +30,23 @@ def get_detailed_serializer(asset_technology, assets=[], asset_technologies=[]): "icon_url": asset_technology.icon_url, "lang": None, "is_deprecated": asset_technology.is_deprecated, + "featured_course": ( + { + "slug": asset_technology.featured_course.slug, + "icon_url": asset_technology.featured_course.icon_url, + "academy": asset_technology.featured_course.academy.id, + "syllabus": ( + [x for x in asset_technology.featured_course.syllabus.all().values_list("id", flat=True)] + if asset_technology.featured_course and asset_technology.featured_course.syllabus + else [] + ), + "color": asset_technology.featured_course.color, + "course_translation": None, + "technologies": asset_technology.featured_course.technologies, + } + if asset_technology.featured_course is not None + else None + ), "marketing_information": asset_technology.marketing_information, "parent": None, "slug": asset_technology.slug, @@ -142,6 +159,32 @@ def test_with_two_asset_technologies__passing_sort_priority__found_for_get_techn # teardown self.bc.database.delete("registry.AssetTechnology") + def test_asset_technology_with_featured_course(self): + + courseModel = self.generate_models(course=1) + + asset_technology = { + "slug": self.bc.fake.slug(), + "title": self.bc.fake.word(), + "featured_course": courseModel.course, + } + + model = self.generate_models( + asset_technology=asset_technology, + ) + + url = reverse_lazy("registry:get_technology_detail", kwargs={"tech_slug": model.asset_technology.slug}) + response = self.client.get(url) + json = response.json() + + expected = get_detailed_serializer(model.asset_technology) + + self.assertEqual(json, expected) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # teardown + self.bc.database.delete("registry.AssetTechnology") + def test_asset_technology_with_marketing_information(self): marketing_info = { "title": {"us": "Practice python", "es": "Practica python"}, @@ -172,6 +215,7 @@ def test_asset_technology_with_marketing_information(self): expected = get_detailed_serializer(model.asset_technology) self.assertEqual(json, expected) + self.assertIsNotNone(json["marketing_information"]["title"]) self.assertEqual(response.status_code, status.HTTP_200_OK) # teardown diff --git a/breathecode/settings.py b/breathecode/settings.py index 1fc486aaf..150112dac 100644 --- a/breathecode/settings.py +++ b/breathecode/settings.py @@ -445,6 +445,13 @@ class Key(TypedDict): class CustomMemCache(LocMemCache): _cache = {} + fake = 1 + + def delete_pattern(self, pattern): + for key in self._cache.keys(): + if fnmatch.fnmatch(key, pattern): + del self._cache[key] + def delete_many(self, patterns): for pattern in patterns: self.delete(pattern) diff --git a/breathecode/tests/mixins/breathecode_mixin/request.py b/breathecode/tests/mixins/breathecode_mixin/request.py index 407ed130c..1058f739b 100644 --- a/breathecode/tests/mixins/breathecode_mixin/request.py +++ b/breathecode/tests/mixins/breathecode_mixin/request.py @@ -122,7 +122,7 @@ def sign_jwt_link( # https://datatracker.ietf.org/doc/html/rfc7519#section-4 payload = { - "sub": user_id, + "sub": str(user_id or ""), "iss": os.getenv("API_URL", "http://localhost:8000"), "app": app.slug, "aud": "breathecode", diff --git a/breathecode/tests/services/google_cloud/tests_credentials.py b/breathecode/tests/services/google_cloud/tests_credentials.py index 307dd5885..99e522949 100644 --- a/breathecode/tests/services/google_cloud/tests_credentials.py +++ b/breathecode/tests/services/google_cloud/tests_credentials.py @@ -76,15 +76,13 @@ def test_resolve_credentials__credentials_file_not_exists__with_env(self, logger result = resolve_credentials() self.assertEqual(result, True) - self.assertEqual( - open_mock.mock_calls, - [ - call(Path(os.path.join(os.getcwd(), ".lacey_mosley.json")), "w"), - call().__enter__(), - call().write("{}\n"), - call().__exit__(None, None, None), - ], - ) + assert open_mock.mock_calls == [ + call(Path(os.path.join(os.getcwd(), ".lacey_mosley.json")), "w"), + call().__enter__(), + call().write("{}\n"), + call().__exit__(None, None, None), + call().close(), + ] self.assertEqual( exists_mock.mock_calls, diff --git a/breathecode/urls.py b/breathecode/urls.py index ccb430529..1cf1b4f24 100644 --- a/breathecode/urls.py +++ b/breathecode/urls.py @@ -34,11 +34,12 @@ path("activity/", include("breathecode.activity.urls.v2", namespace="activity")), path("registry/", include("breathecode.registry.urls.v2", namespace="registry")), path("media/", include("breathecode.media.urls.v2", namespace="media")), + path("auth/", include("breathecode.authenticate.urls.v2", namespace="auth")), ], } apps = [ - ("v1/auth/", "breathecode.authenticate.urls", "auth"), + ("v1/auth/", "breathecode.authenticate.urls.v1", "auth"), ("v1/admissions/", "breathecode.admissions.urls", "admissions"), ("v1/assignment/", "breathecode.assignments.urls", "assignments"), ("v1/freelance/", "breathecode.freelance.urls", "freelance"), diff --git a/breathecode/utils/cache.py b/breathecode/utils/cache.py index 8b0aaa5c9..195b5dc2d 100644 --- a/breathecode/utils/cache.py +++ b/breathecode/utils/cache.py @@ -1,32 +1,34 @@ from __future__ import annotations -import gzip -import zlib -import brotli -import sys + import functools +import gzip +import json import os +import sys +import urllib.parse +import zlib +from datetime import datetime, timedelta from typing import Optional -import urllib.parse, json + +import brotli +import zstandard +from circuitbreaker import circuit from django.core.cache import cache -from datetime import datetime, timedelta from django.db import models -from circuitbreaker import circuit - from django.db.models.fields.related_descriptors import ( - ReverseManyToOneDescriptor, - ManyToManyDescriptor, ForwardManyToOneDescriptor, - ReverseOneToOneDescriptor, ForwardOneToOneDescriptor, + ManyToManyDescriptor, + ReverseManyToOneDescriptor, + ReverseOneToOneDescriptor, ) -import zstandard __all__ = ["Cache", "CACHE_DESCRIPTORS", "CACHE_DEPENDENCIES"] CACHE_DESCRIPTORS: dict[models.Model, Cache] = {} CACHE_DEPENDENCIES: set[models.Model] = set() ENABLE_LIST_OPTIONS = ["true", "1", "yes", "y"] -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False @functools.lru_cache(maxsize=1) diff --git a/breathecode/utils/redis.py b/breathecode/utils/redis.py index bc621cd15..d4ef74c1d 100644 --- a/breathecode/utils/redis.py +++ b/breathecode/utils/redis.py @@ -1,6 +1,6 @@ from django.core.cache import cache -IS_DJANGO_REDIS = hasattr(cache, "delete_pattern") +IS_DJANGO_REDIS = hasattr(cache, "fake") is False __all__ = ["Lock"] diff --git a/breathecode/events/tests/permissions/__init__.py b/breathecode/works/__init__.py similarity index 100% rename from breathecode/events/tests/permissions/__init__.py rename to breathecode/works/__init__.py diff --git a/breathecode/works/admin.py b/breathecode/works/admin.py new file mode 100644 index 000000000..846f6b406 --- /dev/null +++ b/breathecode/works/admin.py @@ -0,0 +1 @@ +# Register your models here. diff --git a/breathecode/works/apps.py b/breathecode/works/apps.py new file mode 100644 index 000000000..5dec25aad --- /dev/null +++ b/breathecode/works/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class WorksConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "breathecode.works" diff --git a/breathecode/events/tests/permissions/contexts/__init__.py b/breathecode/works/migrations/__init__.py similarity index 100% rename from breathecode/events/tests/permissions/contexts/__init__.py rename to breathecode/works/migrations/__init__.py diff --git a/breathecode/works/models.py b/breathecode/works/models.py new file mode 100644 index 000000000..6b2021999 --- /dev/null +++ b/breathecode/works/models.py @@ -0,0 +1 @@ +# Create your models here. diff --git a/breathecode/works/tests.py b/breathecode/works/tests.py new file mode 100644 index 000000000..a39b155ac --- /dev/null +++ b/breathecode/works/tests.py @@ -0,0 +1 @@ +# Create your tests here. diff --git a/breathecode/works/urls.py b/breathecode/works/urls.py new file mode 100644 index 000000000..52a81dece --- /dev/null +++ b/breathecode/works/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from .views import AppUserView, GenericView + +app_name = "works" +urlpatterns = [ + path("app/user", AppUserView.as_view(), name="app_user"), + path("generic", GenericView.as_view(), name="generic"), +] diff --git a/breathecode/works/views.py b/breathecode/works/views.py new file mode 100644 index 000000000..13a3e2119 --- /dev/null +++ b/breathecode/works/views.py @@ -0,0 +1,97 @@ +from adrf.views import APIView +from asgiref.sync import sync_to_async +from capyc.core.i18n import translation +from capyc.rest_framework.exceptions import ValidationException +from django.contrib.auth.models import User +from django.http.request import HttpRequest +from linked_services.django.service import Service +from linked_services.rest_framework.decorators import scope +from linked_services.rest_framework.types import LinkedApp, LinkedHttpRequest, LinkedToken +from rest_framework.permissions import AllowAny +from rest_framework.response import Response + +from breathecode.authenticate.actions import get_user_language +from breathecode.authenticate.serializers import AppUserSerializer +from breathecode.utils.api_view_extensions.api_view_extensions import APIViewExtensions + +# Create your views here. + + +# app/user/:id +class AppUserView(APIView): + permission_classes = [AllowAny] + extensions = APIViewExtensions(paginate=True) + + @scope(["read:user"]) + def get(self, request: LinkedHttpRequest, app: LinkedApp, token: LinkedToken, user_id=None): + handler = self.extensions(request) + lang = get_user_language(request) + + extra = {} + if app.require_an_agreement: + extra["appuseragreement__app__id"] = app.id + + if token.sub: + user = request.get_user() + extra["id"] = user.id + + if user_id: + if "id" in extra and extra["id"] != user_id: + raise ValidationException( + translation( + lang, + en="This user does not have access to this resource", + es="Este usuario no tiene acceso a este recurso", + ), + code=403, + slug="user-with-no-access", + silent=True, + ) + + if "id" not in extra: + extra["id"] = user_id + + user = User.objects.filter(**extra).first() + if not user: + raise ValidationException( + translation(lang, en="User not found", es="Usuario no encontrado"), + code=404, + slug="user-not-found", + silent=True, + ) + + serializer = AppUserSerializer(user, many=False) + return Response(serializer.data) + + if not token.sub and (id := request.GET.get("id")): + extra["id"] = id + + for key in ["email", "username"]: + if key in request.GET: + extra[key] = request.GET.get(key) + + # test this path + items = User.objects.filter(**extra) + items = handler.queryset(items) + serializer = AppUserSerializer(items, many=True) + + return handler.response(serializer.data) + + +class GenericView(APIView): + + @sync_to_async + def get_user(self): + return self.request.user + + async def get(self, request: HttpRequest): + user = await self.get_user() + + params = {} + for key in request.GET.keys(): + params[key] = request.GET.get(key) + + url = "/endpoint" + + async with Service("rigobot", user.id, proxy=True) as s: + return await s.get(url, params=params) diff --git a/conftest.py b/conftest.py index 740e13de1..2f1ca62e3 100644 --- a/conftest.py +++ b/conftest.py @@ -1,5 +1,6 @@ import os -from typing import Generator, Optional +import secrets +from typing import Any, Callable, Generator, Optional from unittest.mock import MagicMock, patch import jwt @@ -8,22 +9,26 @@ from capyc.pytest.django.fixtures.signals import Signals from django.core.cache import cache from django.utils import timezone +from linked_services.django import actions from rest_framework.test import APIClient from breathecode.notify.utils.hook_manager import HookManagerClass -from breathecode.utils.exceptions import TestError # set ENV as test before run django os.environ["ENV"] = "test" os.environ["DATABASE_URL"] = "sqlite:///:memory:" pytest_plugins = ( - "staging.pytest.core", - "capyc.pytest.core", - "capyc.pytest.newrelic", - "capyc.pytest.django", - "capyc.pytest.rest_framework", - "capyc.pytest.circuitbreaker", + # "staging.pytest.core", + "staging.pytest", + # "capyc.pytest.core", + # "capyc.pytest.newrelic", + # "capyc.pytest.django", + # "capyc.pytest.rest_framework", + # "capyc.pytest.circuitbreaker", + "capyc.pytest", + "linked_services.pytest", + "task_manager.pytest.core", ) from breathecode.tests.mixins.breathecode_mixin import Breathecode @@ -142,22 +147,24 @@ def enable_signals(signals: Signals): @pytest.fixture -def patch_request(monkeypatch): +def patch_request( + monkeypatch: pytest.MonkeyPatch, +) -> Generator[Callable[[Optional[list[tuple[Any, Any, int]]]], MagicMock], None, None]: def patcher(conf=None): if not conf: conf = [] def wrapper(*args, **kwargs): - raises = True + found = False for c in conf: if args == c[0].args and kwargs == c[0].kwargs: - raises = False + found = True break - if raises: - raise TestError(f"Avoiding to make a real request to {args} {kwargs}") + if found is False: + raise Exception(f"Avoiding to make a real request to {args} {kwargs}") mock = MagicMock() @@ -174,7 +181,7 @@ def wrapper(*args, **kwargs): return mock mock = MagicMock() - monkeypatch.setattr("requests.api.request", wrapper) + monkeypatch.setattr("requests.api.request", MagicMock(side_effect=wrapper)) return mock @@ -283,7 +290,7 @@ def wrapper( # https://datatracker.ietf.org/doc/html/rfc7519#section-4 payload = { - "sub": user_id, + "sub": str(user_id or ""), "iss": os.getenv("API_URL", "http://localhost:8000"), "app": app.slug, "aud": "breathecode", @@ -312,3 +319,25 @@ def wrapper( client.credentials(HTTP_AUTHORIZATION=f"Link App={app.slug},Token={token}") yield wrapper + + +@pytest.fixture(autouse=True, scope="function") +def get_app_keys() -> Generator[None, None, None]: + actions.get_app_keys.cache_clear() + actions.get_optional_scopes_set.cache_clear() + actions.get_app.cache_clear() + + yield + + +@pytest.fixture(scope="function") +def get_app_signature() -> Generator[Callable[[], dict[str, Any]], None, None]: + def wrapper() -> dict[str, Any]: + return { + "algorithm": "HMAC_SHA512", + "strategy": "JWT", + "public_key": None, + "private_key": secrets.token_hex(64), + } + + yield wrapper diff --git a/staging/pytest/core/fixtures/http.py b/staging/pytest/core/fixtures/http.py index 40b67bfd2..08c7e25a5 100644 --- a/staging/pytest/core/fixtures/http.py +++ b/staging/pytest/core/fixtures/http.py @@ -138,32 +138,32 @@ def amatch(is_request, method, url, kwargs): handlers = { "get": ( self._get, - lambda url, **kwargs: match(is_request=False, method="GET", url=url, kwargs=kwargs), - lambda url, **kwargs: amatch(is_request=False, method="GET", url=url, kwargs=kwargs), + lambda self, url, **kwargs: match(is_request=False, method="GET", url=url, kwargs=kwargs), + lambda self, url, **kwargs: amatch(is_request=False, method="GET", url=url, kwargs=kwargs), ), "post": ( self._post, - lambda url, **kwargs: match(is_request=False, method="POST", url=url, kwargs=kwargs), + lambda self, url, **kwargs: match(is_request=False, method="POST", url=url, kwargs=kwargs), lambda self, url, **kwargs: amatch(is_request=False, method="POST", url=url, kwargs=kwargs), ), "put": ( self._put, - lambda url, **kwargs: match(is_request=False, method="PUT", url=url, kwargs=kwargs), - lambda url, **kwargs: amatch(is_request=False, method="PUT", url=url, kwargs=kwargs), + lambda self, url, **kwargs: match(is_request=False, method="PUT", url=url, kwargs=kwargs), + lambda self, url, **kwargs: amatch(is_request=False, method="PUT", url=url, kwargs=kwargs), ), "delete": ( self._delete, - lambda url, **kwargs: match(is_request=False, method="DELETE", url=url, kwargs=kwargs), - lambda url, **kwargs: amatch(is_request=False, method="DELETE", url=url, kwargs=kwargs), + lambda self, url, **kwargs: match(is_request=False, method="DELETE", url=url, kwargs=kwargs), + lambda self, url, **kwargs: amatch(is_request=False, method="DELETE", url=url, kwargs=kwargs), ), "head": ( self._head, - lambda url, **kwargs: match(is_request=False, method="HEAD", url=url, kwargs=kwargs), - lambda url, **kwargs: amatch(is_request=False, method="HEAD", url=url, kwargs=kwargs), + lambda self, url, **kwargs: match(is_request=False, method="HEAD", url=url, kwargs=kwargs), + lambda self, url, **kwargs: amatch(is_request=False, method="HEAD", url=url, kwargs=kwargs), ), "request": ( self._request, - lambda method, url, **kwargs: match(is_request=True, method=method, url=url, kwargs=kwargs), + lambda self, method, url, **kwargs: match(is_request=True, method=method, url=url, kwargs=kwargs), lambda self, method, url, **kwargs: amatch(is_request=True, method=method, url=url, kwargs=kwargs), ), }