From 436f1d256621940a2d3e39aa6ebc7c4a3748e34d Mon Sep 17 00:00:00 2001 From: Ian Scott Date: Thu, 9 Jan 2025 11:18:02 -0500 Subject: [PATCH 1/3] fix(build): Pinning invenio-logging to avoid conflict --- Pipfile | 6 +- Pipfile.lock | 3496 +++++++++++++++++++++++++++++--------------------- 2 files changed, 2013 insertions(+), 1489 deletions(-) diff --git a/Pipfile b/Pipfile index ed85e0d59..1f08b42e8 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,9 @@ jsonlines = "*" requests-mock = "*" selenium = "*" docker-services-cli = "*" +sphinx = "*" +myst-parser = "*" +furo = "*" [packages] aiohttp = "*" @@ -21,9 +24,10 @@ flask-breadcrumbs = "*" flask-principal = "*" greenlet = {} halo = "*" -invenio-app-rdm = { extras = ["opensearch2"]} +invenio-app-rdm = {version = ">=12.0.0,<13.0.0", extras = ["opensearch2"]} invenio-communities = {editable = true, path = "./site/kcworks/dependencies/invenio-communities"} invenio-group-collections-kcworks = {editable = true, path = "./site/kcworks/dependencies/invenio-group-collections-kcworks"} +invenio-logging = {version = "<2.1.2"} invenio-modular-deposit-form = {editable = true, path = "./site/kcworks/dependencies/invenio-modular-deposit-form"} invenio-modular-detail-page = {editable = true, path = "./site/kcworks/dependencies/invenio-modular-detail-page"} invenio-rdm-records = {editable = true, path = "./site/kcworks/dependencies/invenio-rdm-records"} diff --git a/Pipfile.lock b/Pipfile.lock index 51a0a24e7..b2d2525ee 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2c12afd01d0fb8d1c7f9662e8aec4cfbc6a2fce9e7afa1acdf1121bb38dfa857" + "sha256": "8263d569b7616cf7553e89df84cb2c1127d557a7500d3214310e5f9edf15a0ae" }, "pipfile-spec": 6, "requires": { @@ -18,117 +18,102 @@ "default": { "aiohappyeyeballs": { "hashes": [ - "sha256:4ca893e6c5c1f5bf3888b04cb5a3bee24995398efef6e0b9f747b5e89d84fd74", - "sha256:8522691d9a154ba1145b157d6d5c15e5c692527ce6a53c5e5f9876977f6dab2f" + "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", + "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8" ], "markers": "python_version >= '3.8'", - "version": "==2.4.2" + "version": "==2.4.4" }, "aiohttp": { "hashes": [ - "sha256:10c7932337285a6bfa3a5fe1fd4da90b66ebfd9d0cbd1544402e1202eb9a8c3e", - "sha256:177126e971782769b34933e94fddd1089cef0fe6b82fee8a885e539f5b0f0c6a", - "sha256:1ce46dfb49cfbf9e92818be4b761d4042230b1f0e05ffec0aad15b3eb162b905", - "sha256:1e7a6af57091056a79a35104d6ec29d98ec7f1fb7270ad9c6fff871b678d1ff8", - "sha256:21a72f4a9c69a8567a0aca12042f12bba25d3139fd5dd8eeb9931f4d9e8599cd", - "sha256:21c1925541ca84f7b5e0df361c0a813a7d6a56d3b0030ebd4b220b8d232015f9", - "sha256:21f8225f7dc187018e8433c9326be01477fb2810721e048b33ac49091b19fb4a", - "sha256:22cdeb684d8552490dd2697a5138c4ecb46f844892df437aaf94f7eea99af879", - "sha256:270e653b5a4b557476a1ed40e6b6ce82f331aab669620d7c95c658ef976c9c5e", - "sha256:2df786c96c57cd6b87156ba4c5f166af7b88f3fc05f9d592252fdc83d8615a3c", - "sha256:32710d6b3b6c09c60c794d84ca887a3a2890131c0b02b3cefdcc6709a2260a7c", - "sha256:33a68011a38020ed4ff41ae0dbf4a96a202562ecf2024bdd8f65385f1d07f6ef", - "sha256:365783e1b7c40b59ed4ce2b5a7491bae48f41cd2c30d52647a5b1ee8604c68ad", - "sha256:3a95d2686bc4794d66bd8de654e41b5339fab542b2bca9238aa63ed5f4f2ce82", - "sha256:3b2036479b6b94afaaca7d07b8a68dc0e67b0caf5f6293bb6a5a1825f5923000", - "sha256:3c7f270f4ca92760f98a42c45a58674fff488e23b144ec80b1cc6fa2effed377", - "sha256:3f6d47e392c27206701565c8df4cac6ebed28fdf6dcaea5b1eea7a4631d8e6db", - "sha256:40d2d719c3c36a7a65ed26400e2b45b2d9ed7edf498f4df38b2ae130f25a0d01", - "sha256:4618f0d2bf523043866a9ff8458900d8eb0a6d4018f251dae98e5f1fb699f3a8", - "sha256:471a8c47344b9cc309558b3fcc469bd2c12b49322b4b31eb386c4a2b2d44e44a", - "sha256:4954e6b06dd0be97e1a5751fc606be1f9edbdc553c5d9b57d72406a8fbd17f9d", - "sha256:497a7d20caea8855c5429db3cdb829385467217d7feb86952a6107e033e031b9", - "sha256:4b91f4f62ad39a8a42d511d66269b46cb2fb7dea9564c21ab6c56a642d28bff5", - "sha256:4dbf252ac19860e0ab56cd480d2805498f47c5a2d04f5995d8d8a6effd04b48c", - "sha256:4e10b04542d27e21538e670156e88766543692a0a883f243ba8fad9ddea82e53", - "sha256:5284997e3d88d0dfb874c43e51ae8f4a6f4ca5b90dcf22995035187253d430db", - "sha256:57359785f27394a8bcab0da6dcd46706d087dfebf59a8d0ad2e64a4bc2f6f94f", - "sha256:597128cb7bc5f068181b49a732961f46cb89f85686206289d6ccb5e27cb5fbe2", - "sha256:5aa1a073514cf59c81ad49a4ed9b5d72b2433638cd53160fd2f3a9cfa94718db", - "sha256:680dbcff5adc7f696ccf8bf671d38366a1f620b5616a1d333d0cb33956065395", - "sha256:6984dda9d79064361ab58d03f6c1e793ea845c6cfa89ffe1a7b9bb400dfd56bd", - "sha256:69de056022e7abf69cb9fec795515973cc3eeaff51e3ea8d72a77aa933a91c52", - "sha256:6c7efa6616a95e3bd73b8a69691012d2ef1f95f9ea0189e42f338fae080c2fc6", - "sha256:6d1ad868624f6cea77341ef2877ad4e71f7116834a6cd7ec36ec5c32f94ee6ae", - "sha256:713dff3f87ceec3bde4f3f484861464e722cf7533f9fa6b824ec82bb5a9010a7", - "sha256:71462f8eeca477cbc0c9700a9464e3f75f59068aed5e9d4a521a103692da72dc", - "sha256:7c38cfd355fd86c39b2d54651bd6ed7d63d4fe3b5553f364bae3306e2445f847", - "sha256:8296edd99d0dd9d0eb8b9e25b3b3506eef55c1854e9cc230f0b3f885f680410b", - "sha256:85431c9131a9a0f65260dc7a65c800ca5eae78c4c9931618f18c8e0933a0e0c1", - "sha256:85e4d7bd05d18e4b348441e7584c681eff646e3bf38f68b2626807f3add21aa2", - "sha256:8885ca09d3a9317219c0831276bfe26984b17b2c37b7bf70dd478d17092a4772", - "sha256:8960fabc20bfe4fafb941067cda8e23c8c17c98c121aa31c7bf0cdab11b07842", - "sha256:9443d9ebc5167ce1fbb552faf2d666fb22ef5716a8750be67efd140a7733738c", - "sha256:9721554bfa9e15f6e462da304374c2f1baede3cb06008c36c47fa37ea32f1dc4", - "sha256:98a4eb60e27033dee9593814ca320ee8c199489fbc6b2699d0f710584db7feb7", - "sha256:98fae99d5c2146f254b7806001498e6f9ffb0e330de55a35e72feb7cb2fa399b", - "sha256:9a281cba03bdaa341c70b7551b2256a88d45eead149f48b75a96d41128c240b3", - "sha256:a087c84b4992160ffef7afd98ef24177c8bd4ad61c53607145a8377457385100", - "sha256:a1ba7bc139592339ddeb62c06486d0fa0f4ca61216e14137a40d626c81faf10c", - "sha256:a3081246bab4d419697ee45e555cef5cd1def7ac193dff6f50be761d2e44f194", - "sha256:a72f89aea712c619b2ca32c6f4335c77125ede27530ad9705f4f349357833695", - "sha256:a78ba86d5a08207d1d1ad10b97aed6ea48b374b3f6831d02d0b06545ac0f181e", - "sha256:a961ee6f2cdd1a2be4735333ab284691180d40bad48f97bb598841bfcbfb94ec", - "sha256:ab1546fc8e00676febc81c548a876c7bde32f881b8334b77f84719ab2c7d28dc", - "sha256:ab2d6523575fc98896c80f49ac99e849c0b0e69cc80bf864eed6af2ae728a52b", - "sha256:aff048793d05e1ce05b62e49dccf81fe52719a13f4861530706619506224992b", - "sha256:b1a012677b8e0a39e181e218de47d6741c5922202e3b0b65e412e2ce47c39337", - "sha256:b667e2a03407d79a76c618dc30cedebd48f082d85880d0c9c4ec2faa3e10f43e", - "sha256:b91557ee0893da52794b25660d4f57bb519bcad8b7df301acd3898f7197c5d81", - "sha256:badb51d851358cd7535b647bb67af4854b64f3c85f0d089c737f75504d5910ec", - "sha256:c36074b26f3263879ba8e4dbd33db2b79874a3392f403a70b772701363148b9f", - "sha256:c4916070e12ae140110aa598031876c1bf8676a36a750716ea0aa5bd694aa2e7", - "sha256:c6769d71bfb1ed60321363a9bc05e94dcf05e38295ef41d46ac08919e5b00d19", - "sha256:c887019dbcb4af58a091a45ccf376fffe800b5531b45c1efccda4bedf87747ea", - "sha256:cd9716ef0224fe0d0336997eb242f40619f9f8c5c57e66b525a1ebf9f1d8cebe", - "sha256:ceacea31f8a55cdba02bc72c93eb2e1b77160e91f8abd605969c168502fd71eb", - "sha256:d088ca05381fd409793571d8e34eca06daf41c8c50a05aeed358d2d340c7af81", - "sha256:d3a79200a9d5e621c4623081ddb25380b713c8cf5233cd11c1aabad990bb9381", - "sha256:d82404a0e7b10e0d7f022cf44031b78af8a4f99bd01561ac68f7c24772fed021", - "sha256:d95ae4420669c871667aad92ba8cce6251d61d79c1a38504621094143f94a8b4", - "sha256:da57af0c54a302b7c655fa1ccd5b1817a53739afa39924ef1816e7b7c8a07ccb", - "sha256:ddb9b9764cfb4459acf01c02d2a59d3e5066b06a846a364fd1749aa168efa2be", - "sha256:de23085cf90911600ace512e909114385026b16324fa203cc74c81f21fd3276a", - "sha256:e1f0f7b27171b2956a27bd8f899751d0866ddabdd05cbddf3520f945130a908c", - "sha256:e32148b4a745e70a255a1d44b5664de1f2e24fcefb98a75b60c83b9e260ddb5b", - "sha256:e45fdfcb2d5bcad83373e4808825b7512953146d147488114575780640665027", - "sha256:e56bb7e31c4bc79956b866163170bc89fd619e0581ce813330d4ea46921a4881", - "sha256:e860985f30f3a015979e63e7ba1a391526cdac1b22b7b332579df7867848e255", - "sha256:ee3587506898d4a404b33bd19689286ccf226c3d44d7a73670c8498cd688e42c", - "sha256:ee97c4e54f457c366e1f76fbbf3e8effee9de57dae671084a161c00f481106ce", - "sha256:ef9b484604af05ca745b6108ca1aaa22ae1919037ae4f93aaf9a37ba42e0b835", - "sha256:f21e8f2abed9a44afc3d15bba22e0dfc71e5fa859bea916e42354c16102b036f", - "sha256:f23a6c1d09de5de89a33c9e9b229106cb70dcfdd55e81a3a3580eaadaa32bc92", - "sha256:f5d5d5401744dda50b943d8764508d0e60cc2d3305ac1e6420935861a9d544bc", - "sha256:f78e2a78432c537ae876a93013b7bc0027ba5b93ad7b3463624c4b6906489332", - "sha256:f8179855a4e4f3b931cb1764ec87673d3fbdcca2af496c8d30567d7b034a13db", - "sha256:fc0e7f91705445d79beafba9bb3057dd50830e40fe5417017a76a214af54e122", - "sha256:fe285a697c851734285369614443451462ce78aac2b77db23567507484b1dc6f", - "sha256:fe3d79d6af839ffa46fdc5d2cf34295390894471e9875050eafa584cb781508d", - "sha256:fecd55e7418fabd297fd836e65cbd6371aa4035a264998a091bbf13f94d9c44d", - "sha256:ffef3d763e4c8fc97e740da5b4d0f080b78630a3914f4e772a122bbfa608c1db" + "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" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==3.10.8" + "markers": "python_version >= '3.9'", + "version": "==3.11.11" }, "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" }, "alabaster": { "hashes": [ @@ -148,11 +133,11 @@ }, "amqp": { "hashes": [ - "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637", - "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd" + "sha256:43b3319e1b4e7d1251833a93d672b4af1e40f3d632d479b98661a95f117880a2", + "sha256:cddc00c725449522023bad949f70fff7b48f0b1ade74d170a6f10ab044739432" ], "markers": "python_version >= '3.6'", - "version": "==5.2.0" + "version": "==5.3.1" }, "aniso8601": { "hashes": [ @@ -178,27 +163,28 @@ }, "asttokens": { "hashes": [ - "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", - "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0" + "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", + "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2" ], - "version": "==2.4.1" + "markers": "python_version >= '3.8'", + "version": "==3.0.0" }, "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" }, "babel": { "hashes": [ @@ -210,10 +196,10 @@ }, "babel-edtf": { "hashes": [ - "sha256:728d6d4b787356cdfcca61980a8b9b41b00edf96cec66fb2ee1035196b9c9643", - "sha256:93c80d6b5c227f6da5a5b8ae8b8a2f18a60706b18a0dbd00f28a609437db3295" + "sha256:1ed0c454e123ed7579510d9531eae5af4399272b0dff897d3d42f68e9bed8d8e", + "sha256:706529185b335f05ca4567c468f4ec307ad36fa9ce13b63671f1e113a57f7d55" ], - "version": "==1.1.4" + "version": "==1.2.1" }, "base32-lib": { "hashes": [ @@ -224,17 +210,17 @@ }, "beautifulsoup4": { "hashes": [ - "sha256:7e05ad0b6c26108d9990e2235e8a9b4e2c03ead6f391ceb60347f8ebea6b80ba", - "sha256:c684ddec071aa120819889aa9e8940f85c3f3cdaa08e23b9fa26510387897bd5" + "sha256:237484d61be5d1e82b5aedd8568eea763b76191ee146597b1d405e28dbd9f3d9", + "sha256:4970105b2620a2fa530de34c76a9063c8f22d393f639d718d939f0750cc4473d" ], "markers": "python_full_version >= '3.6.0'", - "version": "==4.13.0b2" + "version": "==4.13.0b3" }, "bibtexparser": { "hashes": [ - "sha256:e00e29e24676c4808e0b4333b37bb55cca9cbb7871a56f63058509281588d789" + "sha256:a9c7ded64bc137720e4df0b1b7f12734edc1361185f1c9097048ff7c35af2b8f" ], - "version": "==1.4.1" + "version": "==1.4.3" }, "billiard": { "hashes": [ @@ -252,44 +238,47 @@ "version": "==0.4.4" }, "bleach": { + "extras": [ + "css" + ], "hashes": [ - "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe", - "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6" + "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", + "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f" ], - "markers": "python_version >= '3.8'", - "version": "==6.1.0" + "markers": "python_version >= '3.9'", + "version": "==6.2.0" }, "blinker": { "hashes": [ - "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01", - "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83" + "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", + "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc" ], - "markers": "python_version >= '3.8'", - "version": "==1.8.2" + "markers": "python_version >= '3.9'", + "version": "==1.9.0" }, "boto3": { "hashes": [ - "sha256:2244044cdfa8ac345d7400536dc15a4824835e7ec5c55bc267e118af66bb27db", - "sha256:7bbb1ee649e09e956952285782cfdebd7e81fc78384f48dfab3d66c6eaf3f63f" + "sha256:516c514fb447d6f216833d06a0781c003fcf43099a4ca2f5a363a8afe0942070", + "sha256:5aa606239f0fe0dca0506e0ad6bbe4c589048e7e6c2486cee5ec22b6aa7ec2f8" ], "markers": "python_version >= '3.8'", - "version": "==1.35.29" + "version": "==1.35.94" }, "botocore": { "hashes": [ - "sha256:4ed28ab03675bb008a290c452c5ddd7aaa5d4e3fa1912aadbdf93057ee84362b", - "sha256:f8e3ae0d84214eff3fb69cb4dc51cea6c43d3bde82027a94d00c52b941d6c3d5" + "sha256:2b3309b356541faa4d88bb957dcac1d8004aa44953c0b7d4521a6cc5d3d5d6ba", + "sha256:d784d944865d8279c79d2301fc09ac28b5221d4e7328fb4e23c642c253b9932c" ], "markers": "python_version >= '3.8'", - "version": "==1.35.29" + "version": "==1.35.94" }, "build": { "hashes": [ - "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c", - "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613" + "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", + "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7" ], "markers": "python_version >= '3.8'", - "version": "==1.2.2" + "version": "==1.2.2.post1" }, "cachelib": { "hashes": [ @@ -360,11 +349,11 @@ }, "certifi": { "hashes": [ - "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", + "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db" ], "markers": "python_version >= '3.6'", - "version": "==2024.8.30" + "version": "==2024.12.14" }, "cffi": { "hashes": [ @@ -436,7 +425,7 @@ "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" ], - "markers": "platform_python_implementation != 'PyPy'", + "markers": "python_version >= '3.8'", "version": "==1.17.1" }, "chardet": { @@ -449,107 +438,109 @@ }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "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.3.2" + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "check-manifest": { "hashes": [ - "sha256:058cd30057714c39b96ce4d83f254fc770e3145c7b1932b5940b4e3efb5521ef", - "sha256:64a640445542cf226919657c7b78d02d9c1ca5b1c25d7e66e0e1ff325060f416" + "sha256:6ab3e3aa72a008da3314b432f4c768c9647b4d6d8032f9e1a4672a572118e48c", + "sha256:d300f9f292986aa1a30424af44eb45c5644e0a810e392e62d553b24bb3393494" ], "markers": "python_version >= '3.7'", - "version": "==0.49" + "version": "==0.50" }, "citeproc-py": { "hashes": [ @@ -568,11 +559,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-default-group": { "hashes": [ @@ -648,114 +639,104 @@ "toml" ], "hashes": [ - "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", - "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", - "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", - "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989", - "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", - "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", - "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", - "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", - "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", - "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", - "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", - "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", - "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", - "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", - "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", - "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8", - "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", - "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", - "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", - "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", - "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", - "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", - "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", - "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", - "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", - "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0", - "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", - "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", - "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", - "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", - "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", - "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", - "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", - "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", - "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de", - "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", - "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", - "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569", - "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", - "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", - "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", - "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", - "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", - "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6", - "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", - "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", - "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", - "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", - "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", - "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b", - "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", - "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", - "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3", - "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", - "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", - "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", - "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", - "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", - "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", - "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", - "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", - "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", - "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7", - "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", - "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", - "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", - "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", - "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", - "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a", - "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", - "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", - "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc" + "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" ], - "markers": "python_version >= '3.8'", - "version": "==7.6.1" + "markers": "python_version >= '3.9'", + "version": "==7.6.10" }, "cryptography": { "hashes": [ - "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494", - "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806", - "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d", - "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062", - "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2", - "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", - "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1", - "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85", - "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84", - "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042", - "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d", - "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962", - "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2", - "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa", - "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d", - "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365", - "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96", - "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47", - "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d", - "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d", - "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c", - "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb", - "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277", - "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172", - "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034", - "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a", - "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289" - ], - "markers": "python_version >= '3.7'", - "version": "==43.0.1" + "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" + ], + "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", + "version": "==44.0.0" }, "cssselect2": { "hashes": [ @@ -767,10 +748,10 @@ }, "datacite": { "hashes": [ - "sha256:139ce49b0d995ee346bffaf3d884a4ed0674696372a7079c7e3a092d82953156", - "sha256:1850edcca821d8ac58b441f09780f9ce6f93df832b6da9039d3bb9c0226e3b5d" + "sha256:be2731b189ddc558a42efcd402268f03edbc206fe1030c80147c1c48cc7552a7", + "sha256:e506dc6ce62bd930d6980b32c07c3186f3dfc8d327cd2f817b8423e4f9dd171d" ], - "version": "==1.1.4" + "version": "==1.2.0" }, "dateparser": { "hashes": [ @@ -797,11 +778,11 @@ }, "deepdiff": { "hashes": [ - "sha256:245599a4586ab59bb599ca3517a9c42f3318ff600ded5e80a3432693c8ec3c4b", - "sha256:42e99004ce603f9a53934c634a57b04ad5900e0d8ed0abb15e635767489cbc05" + "sha256:b0231fa3afb0f7184e82535f2b4a36636442ed21e94a0cf3aaa7982157e7ebca", + "sha256:dd7bc7d5c8b51b5b90f01b0e2fe23c801fd8b4c6a7ee7e31c5a3c3663fcc7ceb" ], "markers": "python_version >= '3.8'", - "version": "==8.0.1" + "version": "==8.1.1" }, "defusedxml": { "hashes": [ @@ -813,11 +794,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" }, "dictdiffer": { "hashes": [ @@ -828,18 +809,18 @@ }, "distlib": { "hashes": [ - "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", - "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64" + "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", + "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403" ], - "version": "==0.3.8" + "version": "==0.3.9" }, "dnspython": { "hashes": [ - "sha256:41db6ac9d09cee920af813e6bdcddcfe0bdf441682c614d4d99512b805c85b0e", - "sha256:a39c1061f6866c5c5f46892604f1cc88e75a418a380938b66743709a642487d9" + "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", + "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1" ], "markers": "python_version >= '3.9'", - "version": "==2.7.0rc1" + "version": "==2.7.0" }, "docker": { "hashes": [ @@ -874,10 +855,11 @@ }, "edtf": { "hashes": [ - "sha256:4f4a7425a4a32862f5870de4facecc9050f01a57e19394eb9739fb970cab810e", - "sha256:744135d392774c636425d8ed6dc9182093f2c0174ca9f3f7968588b0168d826c" + "sha256:7393c570b4838c8cbc05b0687c6ea0578039ba007c8ce125206f44f18f2dea5d", + "sha256:b38ca29fa166a5c628b899a76e73a9f4cc732da565b85e737af4c0e457775f5e" ], - "version": "==4.0.1" + "markers": "python_version >= '3.8'", + "version": "==5.0.0" }, "email-validator": { "hashes": [ @@ -898,7 +880,7 @@ "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" ], - "markers": "python_version < '3.11'", + "markers": "python_version >= '3.7'", "version": "==1.2.2" }, "executing": { @@ -911,18 +893,18 @@ }, "faker": { "hashes": [ - "sha256:bf0207af5777950054a2a3b43f4b5bdc33b585918d2b28f1dab52ac0ffe2bac0", - "sha256:f0a60009150736c1c033bea31aa19ae63071c9dcf10adfaf9f1a87a3add84bc8" + "sha256:2abb551a05b75d268780b6095100a48afc43c53e97422002efbfc1272ebf5f26", + "sha256:ae074d9c7ef65817a93b448141a5531a16b2ea2e563dc5774578197c7c84060c" ], "markers": "python_version >= '3.8'", - "version": "==30.0.0" + "version": "==33.3.0" }, "fastjsonschema": { "hashes": [ - "sha256:3d48fc5300ee96f5d116f10fe6f28d938e6008f59a6a025c2649475b87f76a23", - "sha256:5875f0b0fa7a0043a91e93a9b8f793bcbbba9691e7fd83dca95c28ba26d21f0a" + "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", + "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667" ], - "version": "==2.20.0" + "version": "==2.21.1" }, "filelock": { "hashes": [ @@ -1020,9 +1002,10 @@ }, "flask-kvsession-invenio": { "hashes": [ - "sha256:fe24405403fff9e3ab2c5a34d93362d63ada4c9e5e7afab850ea4f80efb92a85" + "sha256:4c49a34bc3c1f4b53175d10514769818ec861febd129a3b545ebf9a8ad5d7bbb", + "sha256:5f153ccdab2ec013b9be23e80faa995f872b8559c9bce6322e1a5cb260e3fde4" ], - "version": "==0.6.3" + "version": "==0.6.4" }, "flask-limiter": { "hashes": [ @@ -1085,11 +1068,11 @@ }, "flask-security-invenio": { "hashes": [ - "sha256:b27aecd4c2294287d2c3341dfdcd0d5a431fcc2af7d77f86e8adfbb98728ab71", - "sha256:f638c77f8e56a5f56ad5a133ae87b4751226aec9aa077e08b12f12be4d1e6798" + "sha256:8d8ad6e4ce2441fe6ae4c33f9ef0f2f5e0228f039667918c477fef63c877d50e", + "sha256:dc6b9095c1e145b43e3a7a9c945313da16fb298a5250414cc21405e301673cf6" ], "markers": "python_version >= '3.6'", - "version": "==3.3.3" + "version": "==3.4.0" }, "flask-shell-ipython": { "hashes": [ @@ -1116,101 +1099,117 @@ }, "flask-webpackext": { "hashes": [ - "sha256:36e4b2d19f3e12e0bb370248094e1631a0cf8e607e76ca8c437718395b90c7ad", - "sha256:6313903d5aad5f330cb14ce97e7fec22541da413d5fe71b33b1f1a2eb69e426f" + "sha256:7432c2e8d9039238f2f8476b004520278cd13ea3f802f9695536f273dce67f7e", + "sha256:7b9d382d13de23e722095727038201cdeca1f046f3c287eae81271e9336062d8" ], - "version": "==1.0.2" + "markers": "python_version >= '3.7'", + "version": "==2.0.0" }, "flask-wtf": { "hashes": [ - "sha256:8bb269eb9bb46b87e7c8233d7e7debdf1f8b74bf90cc1789988c29b37a97b695", - "sha256:fa6793f2fb7e812e0fe9743b282118e581fb1b6c45d414b8af05e659bd653287" + "sha256:79d2ee1e436cf570bccb7d916533fa18757a2f18c290accffab1b9a0b684666b", + "sha256:e93160c5c5b6b571cf99300b6e01b72f9a101027cab1579901f8b10c5daf0b70" ], - "markers": "python_version >= '3.8'", - "version": "==1.2.1" + "markers": "python_version >= '3.9'", + "version": "==1.2.2" }, "frozenlist": { "hashes": [ - "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", - "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", - "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", - "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", - "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", - "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", - "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", - "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", - "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", - "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", - "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", - "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", - "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", - "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", - "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", - "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", - "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", - "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", - "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", - "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", - "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", - "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", - "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", - "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", - "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", - "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", - "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", - "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", - "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", - "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", - "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", - "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", - "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", - "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", - "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", - "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", - "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", - "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", - "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", - "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", - "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", - "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", - "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", - "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", - "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", - "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", - "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", - "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", - "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", - "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", - "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", - "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", - "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", - "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", - "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", - "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", - "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", - "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", - "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", - "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", - "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", - "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", - "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", - "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", - "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", - "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", - "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", - "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", - "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", - "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", - "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", - "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", - "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", - "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", - "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", - "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", - "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74" + "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", + "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf", + "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6", + "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a", + "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d", + "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f", + "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28", + "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b", + "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9", + "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2", + "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec", + "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2", + "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c", + "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336", + "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4", + "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d", + "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b", + "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c", + "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10", + "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08", + "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942", + "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", + "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f", + "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10", + "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5", + "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", + "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", + "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c", + "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d", + "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923", + "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608", + "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de", + "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17", + "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0", + "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", + "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641", + "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c", + "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a", + "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0", + "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", + "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab", + "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f", + "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3", + "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", + "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", + "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604", + "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", + "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5", + "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03", + "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", + "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953", + "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", + "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d", + "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", + "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3", + "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", + "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", + "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9", + "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf", + "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76", + "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba", + "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171", + "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb", + "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439", + "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", + "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972", + "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d", + "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869", + "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9", + "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411", + "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723", + "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2", + "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b", + "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99", + "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e", + "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840", + "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3", + "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb", + "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", + "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0", + "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca", + "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45", + "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e", + "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f", + "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5", + "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307", + "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e", + "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2", + "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778", + "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a", + "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30", + "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a" ], "markers": "python_version >= '3.8'", - "version": "==1.4.1" + "version": "==1.5.0" }, "fs": { "hashes": [ @@ -1221,11 +1220,11 @@ }, "fsspec": { "hashes": [ - "sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8", - "sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b" + "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f", + "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2" ], "markers": "python_version >= '3.8'", - "version": "==2024.9.0" + "version": "==2024.12.0" }, "ftfy": { "hashes": [ @@ -1238,16 +1237,16 @@ "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.0.0" }, "geojson": { "hashes": [ - "sha256:58a7fa40727ea058efc28b0e9ff0099eadf6d0965e04690830208d3ef571adac", - "sha256:68a9771827237adb8c0c71f8527509c8f5bef61733aa434cefc9c9d4f0ebe8f3" + "sha256:69d14156469e13c79479672eafae7b37e2dcd19bdfd77b53f74fa8fe29910b52", + "sha256:b860baba1e8c6f71f8f5f6e3949a694daccf40820fa8f138b3f712bd85804903" ], "markers": "python_version >= '3.7'", - "version": "==3.1.0" + "version": "==3.2.0" }, "ghp-import": { "hashes": [ @@ -1343,6 +1342,14 @@ "markers": "python_version >= '3.7'", "version": "==3.1.1" }, + "h11": { + "hashes": [ + "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", + "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" + ], + "markers": "python_version >= '3.7'", + "version": "==0.14.0" + }, "halo": { "hashes": [ "sha256:5350488fb7d2aa7c31a1344120cee67a872901ce8858f60da7946cef96c208ab", @@ -1362,11 +1369,11 @@ }, "humanize": { "hashes": [ - "sha256:06b6eb0293e4b85e8d385397c5868926820db32b9b654b932f57fa41c23c9978", - "sha256:39e7ccb96923e732b5c2e27aeaa3b10a8dfeeba3eb965ba7b74a3eb0e30040a6" + "sha256:b53caaec8532bcb2fff70c8826f904c35943f8cecaca29d272d9df38092736c0", + "sha256:e66f36020a2d5a974c504bd2555cf770621dbdbb6d82f94a6857c0b1ea2608be" ], - "markers": "python_version >= '3.8'", - "version": "==4.10.0" + "markers": "python_version >= '3.9'", + "version": "==4.11.0" }, "idna": { "hashes": [ @@ -1378,11 +1385,11 @@ }, "idutils": { "hashes": [ - "sha256:908aabada07bb26e5e8f2d78ff222611b493cd721a05f1451f96d373a48f504d", - "sha256:d09220edd893c3164837890f0d1da303111a16a231dd9dd331c64d3d6f2b52cb" + "sha256:77f5cad0df56dcf7c9368ecbb0f6b1f418340028949e84640731a88e4159eadd", + "sha256:bcd1c88dca6d8d191649aea4e6bebc90258e755f1d5f1770a7ccc736836351a6" ], "markers": "python_version >= '3.7'", - "version": "==1.2.1" + "version": "==1.4.2" }, "imagesize": { "hashes": [ @@ -1402,11 +1409,11 @@ }, "importlib-resources": { "hashes": [ - "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065", - "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717" + "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", + "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec" ], - "markers": "python_version >= '3.8'", - "version": "==6.4.5" + "markers": "python_version >= '3.9'", + "version": "==6.5.2" }, "infinity": { "hashes": [ @@ -1431,27 +1438,27 @@ }, "invenio-access": { "hashes": [ - "sha256:b2627255dc13dba29932e27a599a9e753f1cffa383012b581ffc213856c1aa54", - "sha256:d56ae0c2448b7a5c2bd85d81ae2e57ca6c65399ab3846bb9480d0911df42c565" + "sha256:27f4037e0482802ec8691ccb131f1b1007c622cb39a160d9797c9bd512b418e5", + "sha256:5304393066cc53ed62c8905bd605637c85c4000b0f9854c4b80d7a36cca63c77" ], "markers": "python_version >= '3.7'", - "version": "==2.0.0" + "version": "==2.1.0" }, "invenio-accounts": { "hashes": [ - "sha256:8cedb621565536628afa5ef45b975b9c619f5296e24f2ab733ab5d49a3fb3e8e", - "sha256:a9f4af49177cc33114bc06dc2ca50d76433484235c1de6a7e7266ad29288e291" + "sha256:279a1e08e4abebc790c2a2977b9ab1f051880bbc47d4823be058cc60a3e505c7", + "sha256:a715360207f8a284e5182c29ab48e4e5d1aa7180d62b548ff300772adbfa97a5" ], "markers": "python_version >= '3.7'", - "version": "==5.1.2" + "version": "==5.1.7" }, "invenio-admin": { "hashes": [ - "sha256:2c1138d5664c8d6e76bfb7378960b1945fb4af3dda325515aab68f33e1e5f4ae", - "sha256:2e257df24e300d992799d377a3ca7bbf64e7c7002a9b8890ee56667a2209d76a" + "sha256:38092d15defb2f2591e4bffe0ed2d1463af2748441af6a02083b133c7467e9e0", + "sha256:aacaccaf099499e34e07fb0b5ce069e00637910eb43d2de9fe1b94aa67bc07a3" ], "markers": "python_version >= '3.7'", - "version": "==1.4.0" + "version": "==1.4.1" }, "invenio-administration": { "hashes": [ @@ -1463,11 +1470,11 @@ }, "invenio-app": { "hashes": [ - "sha256:9c35dfdedc9071a64b7050eb1d75a6143e362dfb0a60f815488c3ee09aabdabe", - "sha256:a2fcb3d53763ca916346643b31c9019cf591d04f8382f5e7a23061a9fa6a3afd" + "sha256:5350b549203a813d07dfb383d672d709abb48463482e0780a5139fe44e935b3c", + "sha256:e22a3c08ffe57b992eecf05346bb3346571fca492babae2b065a089e73df5bfb" ], "markers": "python_version >= '3.7'", - "version": "==1.5.0" + "version": "==1.5.1" }, "invenio-app-rdm": { "extras": [ @@ -1482,19 +1489,19 @@ }, "invenio-assets": { "hashes": [ - "sha256:578fb3b7fdc4c0cc34ee7e3be3dd49e880d3fbc225499b09d54cfedec92fb48d", - "sha256:620dffcaf228dd947aab9fc74f62bad20444a8f494ba2dda177c7b88e393c7d0" + "sha256:0641235db3687941f486f8cb2c0a59186130c2db79b7ec459ef10e6e736c36bd", + "sha256:0e5d86363a7088353ca24dce63df87278d82c98ada80db79222530cdac19aa6c" ], "markers": "python_version >= '3.7'", - "version": "==3.0.3" + "version": "==3.1.0" }, "invenio-banners": { "hashes": [ - "sha256:248202b91175d1d2966a1bce18786037260cc13ff9beb77c5976b45a40a06bec", - "sha256:cac8534eca75a993536020dc3cc797363096ddb12740ea68429428342ec337a5" + "sha256:671f9765a0a5ddab81a27c796319759a1f72a1dbde8574303439fba19ff35452", + "sha256:fb4f78b14b52db45069643deee511d6dd42b23f03f9d5b44202e6d17588c53f1" ], "markers": "python_version >= '3.7'", - "version": "==3.1.1" + "version": "==3.2.0" }, "invenio-base": { "hashes": [ @@ -1506,19 +1513,19 @@ }, "invenio-cache": { "hashes": [ - "sha256:0eda8356cdbe4992d99bb88453b2fc019aff4b839d5425929c9b3909d3942745", - "sha256:f7d9df0ccdbe8ca7ce994fb3e8418a21c176ce982d1862f6c1c4167f2326aa1b" + "sha256:6c53c84c71390daa7348d81cd98217a22437279330049cbfb44d633b54f6b2a5", + "sha256:df11bbd387c11450952c7ba059353a9ceb8a678cdddeaba6eae8dc6fab8c1ffb" ], "markers": "python_version >= '3.7'", - "version": "==1.3.0" + "version": "==1.3.1" }, "invenio-celery": { "hashes": [ - "sha256:b121f64c21329faad1a5e6deae06fe9949c0fab226bd4447502ac143e9202c3c", - "sha256:d5c001ccd80a788159b5f643b7cd20312e65b75670f2c3f7bf09ddf29cda9b16" + "sha256:3698d61fcca5f3fc2f643939df85084bb5849b4af0a54415c7f6eecfd8b9f14c", + "sha256:f8ead8ea0c94fc0fc7cc905e4280c46e57a44d1cf0e299a06e01f12952772466" ], "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "version": "==1.3.2" }, "invenio-cli": { "hashes": [ @@ -1547,11 +1554,11 @@ "postgresql" ], "hashes": [ - "sha256:c02120e22d22498fcd23c3761a1d160c177261c760c38ccfddb4d671fcb7ddef", - "sha256:cbbe6d53678a04e21afd8220498a9ddde041bf5c7afd66df00fb46907b109c13" + "sha256:275307e6a6980140f05ce765f54e0efc5f91a09cf206bdeecea874251f3aafbb", + "sha256:9f07739b8854185b594ea7917dfb8443ffb309981c60d2f660da3e2c12fe7a2d" ], "markers": "python_version >= '3.7'", - "version": "==1.1.5" + "version": "==1.3.1" }, "invenio-drafts-resources": { "hashes": [ @@ -1563,27 +1570,27 @@ }, "invenio-files-rest": { "hashes": [ - "sha256:7feb4484482a34a12a4c6db38455d87a3113a4fe67273a91a4ec66b03e00802e", - "sha256:93dec6ef21846d75ccfc0da7ba661a75b0dd60518895361b37531fdd37d03c90" + "sha256:3d0e6d464e1f51e55ad08f5ac42d969c40cfbd73c02852b9537a55e6541a63d1", + "sha256:59569863adc1bf8a21a0205e9fa4ad9633808edcf6d13226557baa3e5bea0188" ], "markers": "python_version >= '3.7'", - "version": "==2.2.1" + "version": "==2.2.4" }, "invenio-formatter": { "hashes": [ - "sha256:17aee69fb74f369971d2f30401bef2b94045c4eac8d01db04f2b113711d2f1f0", - "sha256:e3ac8f121df9af570845f544d7ac034c75fcfa7e47854b2ec40043cb0f5e32df" + "sha256:7aee94ec01c3cabc6da57825df3352a12f8b91a2e69c7599bdf001febf6bed05", + "sha256:9323dea423927829a332cee7ae1d4c0d127a51709cec612f17da8d5cb1a7f711" ], "markers": "python_version >= '3.8'", - "version": "==2.0.3" + "version": "==2.0.4" }, "invenio-github": { "hashes": [ - "sha256:26cf1efaa1961072325cb5ced42377fb33d88f8a65c4bbe72e74af133060974a", - "sha256:77c38f1a6158f8ba1eab9431f6903849385331dc757184273cdcf8bba07a4a11" + "sha256:91446729f8c23815ddb50b26601a4ccd4faba9635eef401d09b26847400df5ef", + "sha256:d4fe85985e44cce999fa433662962d841b2a26a782073973f9be7b48694e70b6" ], "markers": "python_version >= '3.7'", - "version": "==1.5.2" + "version": "==1.5.4" }, "invenio-group-collections-kcworks": { "editable": true, @@ -1591,26 +1598,27 @@ }, "invenio-i18n": { "hashes": [ - "sha256:6f39224abb3e26c32d670ba1828f4d147acc0e8cca0671ce66862a5264ce75ef", - "sha256:ca66b3d226f963d765c71c7fcbbf7ff2f5977db3cd0b84893073bda4655f99a9" + "sha256:57ccb74ab41061d7930e708ff812d76b03d496d37b17d1833421e175f30748db", + "sha256:61651313bd0a8c0d5f8b6dc59fe45c52e8c0bb01f0f9488fd23159e27fd89ad9" ], "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==2.2.0" }, "invenio-indexer": { "hashes": [ - "sha256:22890d06f770f5e60a2536ff86a54bd0dbd562ae1b025e77fddaaa790753e05f", - "sha256:8a91ec63e424a128fb5d6212a31f6ceed52167f2ab230fdab93e355f49085c14" + "sha256:99d6a7edb63025cc439d87cf18789c89321e23ca8e34aae9775243e9a6402d79", + "sha256:f11c752d7b3cffe4db6a659106e48316963b4771505e0a72375339eea1be7ba0" ], "markers": "python_version >= '3.7'", - "version": "==2.3.0" + "version": "==2.4.0" }, "invenio-jsonschemas": { "hashes": [ - "sha256:95b37b1edb38b3eb10a3ef6fe280bc628a88b7b905efb5d0b57990dca2c1be19", - "sha256:99e406e1032812cabbd6c033645eb16739b275b91e8108061a4e98a896572d26" + "sha256:0ef364acbfb74d382ae83904f3d5390faa893902f25e88110ff18275ab36863b", + "sha256:dedec03de1eb6798ee54d684b0188a9a616f11a508054463e158c473cbcaea07" ], - "version": "==1.1.4" + "markers": "python_version >= '3.7'", + "version": "==1.1.5" }, "invenio-logging": { "extras": [ @@ -1625,11 +1633,11 @@ }, "invenio-mail": { "hashes": [ - "sha256:7260aff9cd0563fca792e271f85f35cc9756820ca0070298143931437654147a", - "sha256:fa652ba65f7fef1e32b1898bb94131912db882fcdc4980e3649ab41160911c44" + "sha256:171e4c31ad78bea483debc102408732125a68379521b8cb672fb4c143817d45d", + "sha256:50fcc9e48aed84cb039dfb235d2f13f755aacffbc99433665759e3115184566e" ], "markers": "python_version >= '3.7'", - "version": "==2.1.1" + "version": "==2.2.0" }, "invenio-modular-deposit-form": { "editable": true, @@ -1641,59 +1649,59 @@ }, "invenio-notifications": { "hashes": [ - "sha256:5a172c3e0d6d5f877eaf5985b4292390504814636c7eb98394406dd5572315c1", - "sha256:d881095d67faf06ac46c3fd5a9a89b6a4ff81796149ade5bb1e440c41ddc93be" + "sha256:68a6282795284300e00bbf22e9e05e08158ee856c2aef3e7c5022594625d9deb", + "sha256:80b0ea60f059634ce58fa51c519d13bd822875a5f285c83f652d2b1a97049f83" ], "markers": "python_version >= '3.7'", - "version": "==0.6.0" + "version": "==0.6.1" }, "invenio-oaiserver": { "hashes": [ - "sha256:73dd1dcb2f716ccf62cafd407aa0ce02c2500079a671fb22df3eb9b73c19a239", - "sha256:c037215dc0a6019f6a602f84f68d3ef74ee3c2311c654f1165aa7b06ace03e81" + "sha256:0315e7042db09fc6599592bd8071def1e48f36a8d2ca9fda44da87fa009992d2", + "sha256:818181e6bec9b4169065ed618a3d13fdef88ad37223195714b37288a2151be71" ], "markers": "python_version >= '3.7'", - "version": "==2.2.3" + "version": "==2.3.0" }, "invenio-oauth2server": { "hashes": [ - "sha256:0b18b2c228f6cb8af3925eb9cc7f962ece4ec27e3817378c10a7a77f9c236b58", - "sha256:4a8173b3716a0e0fb48655223f3a37738d165c27c1f353e105fe3baf1651c0e9" + "sha256:3619e0d29f05acfb6589b929e2bb0e10422265f17b71ff3a41458173df70026a", + "sha256:40ab1a6f8d937ca8b723ad38115c8cc436fd51115050a652d2cf07b8a0ac8ac9" ], "markers": "python_version >= '3.7'", - "version": "==2.3.1" + "version": "==2.4.1" }, "invenio-oauthclient": { "hashes": [ - "sha256:087c9732e9f2dabfe59b4ae2cae836b0c2f046badee020d90732fb43e934d47f", - "sha256:1f878930b6c6fd5adae48630ecc4ca2e1abb1da35d0bc0fa062d7f9af50c4cdb" + "sha256:39bf0a33e70ef0305855a4d1832830a6dd489c5e173243a97201584bdf8d8ab9", + "sha256:c49bbbf8ffc5ef00f50ea1650639e3dd9b1f8b5717bf0181be149b7c2f66578b" ], "markers": "python_version >= '3.7'", - "version": "==4.0.2" + "version": "==4.1.3" }, "invenio-pages": { "hashes": [ - "sha256:165d68461e259a0f0847aae0126422817664ac8fc81f56322d1cff531010e7d0", - "sha256:33982d7d3581c7be1f8ccf8b52ed7bf88ff0ccd237247a6c2af76c05870a6b27" + "sha256:3b15fca9e48f8551d2b788d6b2b22c5b1b99b6526d47ecedc89d22ce82b399e0", + "sha256:8f24e40699724576c22c406d26bb3cf2f2de7018d570d47ca2af6ef02e7465ec" ], "markers": "python_version >= '3.7'", - "version": "==4.1.1" + "version": "==4.1.2" }, "invenio-pidstore": { "hashes": [ - "sha256:51eaa9a000b067f2e6fda72603a33d6ecd1d05f43f2f93d4de4d9aa4ad9fb7d9", - "sha256:7b4f398744984c46a8e5730532d0423021b8fa3c576e0f170f74334af6323454" + "sha256:d6f35aacdbe622d2114fdc921f9ae2fe8d3708c4c06a11b5e3f6d768c750b155", + "sha256:f0124a293fc62a559052625f189176272ecc2171d0a3d3d9cf81006278699027" ], "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "version": "==1.3.4" }, "invenio-previewer": { "hashes": [ - "sha256:37d7ab137dd067d19571c41198e0b1d35178c0d0283f9c5d3189016904334cd2", - "sha256:5c0fc0830f7b7bb51146b4ec759350d2e236edd05d1e90278948a179090b13b2" + "sha256:0a803fac1b911ec3b080165ed4ac48bf340bfcad3849275ab68870211fe08075", + "sha256:cf4510acf7bc93e9329280e7c894fca53a5279a73877437afd25e44e6b89cad1" ], "markers": "python_version >= '3.7'", - "version": "==2.2.1" + "version": "==2.2.2" }, "invenio-queues": { "hashes": [ @@ -1714,11 +1722,11 @@ }, "invenio-records": { "hashes": [ - "sha256:c43fe294b58db80e5a778cde48ea1d2e6ed80c6ce53e1950cffe2e3a890289a9", - "sha256:e5691a5bbdbf42b8a3f8985190fad4de163e1a439b08367d2f702c3c6d4a73e5" + "sha256:253649c67174690a7ac4b1c7bdefdea5647bd73e5b067dfea24dc9f254251047", + "sha256:26b6d4c45da343e146c05a13d90db57c6d99d499e8a4c8596fc95fe7e4dbbbf3" ], "markers": "python_version >= '3.7'", - "version": "==2.3.0" + "version": "==2.4.1" }, "invenio-records-files": { "hashes": [ @@ -1729,11 +1737,11 @@ }, "invenio-records-permissions": { "hashes": [ - "sha256:3d99afbcc2d1b34a5db959fce8212e446f5bb4bf19e1c899d2f81bf3ed0ad769", - "sha256:ee807199a17d217335014b7defd0c7c6d86397aaa945e31437e1e5e9eb59e16f" + "sha256:70c74251978986e6a105ccb9747f9e7d13ccac892e7c812c52eab34deadc63b9", + "sha256:84e0374e1d3371dd942c8e2921269237a7f191b10e4d7f3e60021a8b21770772" ], "markers": "python_version >= '3.7'", - "version": "==0.20.0" + "version": "==0.21.0" }, "invenio-records-resources": { "editable": true, @@ -1750,11 +1758,11 @@ }, "invenio-records-ui": { "hashes": [ - "sha256:bf3ce5498e7300b8577a20fff502ddb22287f2648ccd9b267f12db0d417fc966", - "sha256:eae21ceb4d95460699ea586c0bb0a48b64bd4a91f3ab2c8bf8effd41e3aa5b0c" + "sha256:6268690c30ff257a5b1bdb8db33fdead7e6e222b80fb987f3242a47efd869b22", + "sha256:6791a0e458352275e0c0ed4d629d4e624b3b4cb93916f6f7bbce1aa6f01794bf" ], "markers": "python_version >= '3.7'", - "version": "==1.2.1" + "version": "==1.2.2" }, "invenio-remote-api-provisioner": { "editable": true, @@ -1774,28 +1782,29 @@ }, "invenio-rest": { "hashes": [ - "sha256:7c8ff04d6e2460bbf1867e9f8f8220c326a10280b7039f853c7dfaa12b73bf8c", - "sha256:a7e45e36fda31b66067013c1f69b014e65e39cde58636f0499e01fcaf2618799" + "sha256:dc57a22dd45a4043e27e2ca2cee44b2ccb337e6c94d5f5aaf17e1571b3e4f69e", + "sha256:e338f76aaf56a92cd18df3d54532c26f1c77fbeb44f1197fdd98fcc2c78b92ab" ], "markers": "python_version >= '3.7'", - "version": "==1.3.1" + "version": "==1.5.0" }, "invenio-s3": { "hashes": [ - "sha256:81646647ad1a9fe1678921c6b7c6f4777f2fcdcf23bcaaf6043460d114663cdc", - "sha256:e8021c21e32f0101934edb959e9f353019a90eb1cbeba4b7da3a9a1b1ed68fdc" + "sha256:d2afbdc9cb58360ed8e16dd691579f45f4f0d1b37e5c70a789385352c08f9d78", + "sha256:e8c661a7582b60def82621a3011a184dc7460fbdc96cf0428a58cfee0d589432" ], "index": "pypi", - "version": "==1.0.6" + "markers": "python_version >= '3.7'", + "version": "==1.0.7" }, "invenio-saml": { "hashes": [ - "sha256:a1e1a384b3310e7a307434d83d8c6920e0db8e6fd319d02be1fd355f904daeda", - "sha256:f00fb9409c46804e4c8d8f7e63ac52a3ce78be656d21b9da7ddf22c1490227bf" + "sha256:a75d3cfe41fbc705310f459ae9a7c61d887522a6789b7157b10a9f4167881be8", + "sha256:b441aa130985cabe34aa5435ea2358571ac16e0b164ae4b60fb3a7d37b4a8b58" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==1.0.0" + "version": "==1.0.1" }, "invenio-search": { "extras": [ @@ -1818,11 +1827,11 @@ }, "invenio-stats": { "hashes": [ - "sha256:2eb87435361202b6420fee2a08e6b30297012fe30c782508b47ca5f21ba71638", - "sha256:6321e93b7dac4ccde9337c508e20802132815e905175330825e20fad7ae70cd0" + "sha256:295746c334df5bdaab46134165e04b2a05c124b69b84526a324254930591866f", + "sha256:bafbe2f49926af043535590aa6ac00417d11a83ae6799f9c9f42fd3a81ac885e" ], "markers": "python_version >= '3.7'", - "version": "==4.2.0" + "version": "==4.2.1" }, "invenio-subjects-fast": { "hashes": [ @@ -1835,19 +1844,19 @@ }, "invenio-theme": { "hashes": [ - "sha256:78a6e7cde55dd7110faffde2af39549d468873b46d430babdd8b83e9e14bf665", - "sha256:ba71494f5458296d58c7a0694eca1ed8530847859da4eb2b67ff0d70a79a0353" + "sha256:a395716cdb28bd16d77dc5f87980556e53c734f9c761137ee9adbccd58ad5ccf", + "sha256:ddaed82d60176a0b4308a770dfcbac52e4b3acf857374bac1ab4b8e61d89cf5a" ], "markers": "python_version >= '3.7'", - "version": "==3.4.1" + "version": "==3.5.2" }, "invenio-userprofiles": { "hashes": [ - "sha256:3764fbb28080ca7303faeb467ef85d844af1ef45caadb202e833088c8e77a8a1", - "sha256:808ac839aa76a64ba08d913875bbf1f5ebbe255dafe4bd40c59269f1641c99cd" + "sha256:20387f0c598e7ed9798df38dc41070df8c7af32452ebbc77016001d92a2cd345", + "sha256:5383a20a8a14cf71fe5132f8fb83bfcc91a49d696c563310f6f6c7ff4f8f79b2" ], "markers": "python_version >= '3.7'", - "version": "==3.0.0" + "version": "==3.0.1" }, "invenio-users-resources": { "hashes": [ @@ -1903,10 +1912,11 @@ }, "isodate": { "hashes": [ - "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96", - "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9" + "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", + "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6" ], - "version": "==0.6.1" + "markers": "python_version >= '3.7'", + "version": "==0.7.2" }, "isort": { "hashes": [ @@ -1926,19 +1936,19 @@ }, "jedi": { "hashes": [ - "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", - "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" + "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", + "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9" ], "markers": "python_version >= '3.6'", - "version": "==0.19.1" + "version": "==0.19.2" }, "jinja2": { "hashes": [ - "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", - "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" + "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", + "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" ], "markers": "python_version >= '3.7'", - "version": "==3.1.4" + "version": "==3.1.5" }, "jinja2-time": { "hashes": [ @@ -2011,11 +2021,11 @@ }, "jsonschema-specifications": { "hashes": [ - "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", - "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" + "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", + "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf" ], - "markers": "python_version >= '3.8'", - "version": "==2023.12.1" + "markers": "python_version >= '3.9'", + "version": "==2024.10.1" }, "jupyter-client": { "hashes": [ @@ -2047,11 +2057,11 @@ }, "kombu": { "hashes": [ - "sha256:14212f5ccf022fc0a70453bb025a1dcc32782a588c49ea866884047d66e14763", - "sha256:eef572dd2fd9fc614b37580e3caeafdd5af46c1eff31e7fba89138cdb406f2cf" + "sha256:213dc124de2a9dada467aa3387c638d8594e91a9dff2dcf6206cd9c6bcf84a5d", + "sha256:f581f3b2945a46d5de540a8fde920e87725308cfed6bdeed6983fa4124879cd0" ], "markers": "python_version >= '3.8'", - "version": "==5.4.2" + "version": "==5.5.0rc2" }, "langdetect": { "hashes": [ @@ -2063,11 +2073,11 @@ }, "limits": { "hashes": [ - "sha256:6571b0c567bfa175a35fed9f8a954c0c92f1c3200804282f1b8f1de4ad98a953", - "sha256:9767f7233da4255e9904b79908a728e8ec0984c0b086058b4cbbd309aea553f6" + "sha256:0024ebe5a36c905fcff2d30a8e7680840b75ecdb989db10c526e9fabba529b58", + "sha256:0516cec7c0803e0e1ecd48ad2f75547b85e2be5fb343a24e033f1316f5487e31" ], - "markers": "python_version >= '3.8'", - "version": "==3.13.0" + "markers": "python_version >= '3.9'", + "version": "==4.0.0" }, "log-symbols": { "hashes": [ @@ -2229,18 +2239,18 @@ }, "lxml-html-clean": { "hashes": [ - "sha256:177ebe822b39d1b68df7c0c34ba005cb087b23d3791dae87efb3a2bb162ef398", - "sha256:cc34178e34673025c49c3d7f4bd48754e9e4b23875df2308f43c21733d8437fb" + "sha256:40c838bbcf1fc72ba4ce811fbb3135913017b27820d7c16e8bc412ae1d8bc00b", + "sha256:b704f2757e61d793b1c08bf5ad69e4c0b68d6696f4c3c1429982caf90050bcaf" ], - "version": "==0.2.2" + "version": "==0.4.1" }, "mako": { "hashes": [ - "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", - "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc" + "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627", + "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8" ], "markers": "python_version >= '3.8'", - "version": "==1.3.5" + "version": "==1.3.8" }, "markdown": { "hashes": [ @@ -2252,77 +2262,78 @@ }, "markupsafe": { "hashes": [ - "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", - "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", - "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", - "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", - "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", - "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", - "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", - "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", - "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", - "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", - "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", - "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", - "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", - "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", - "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", - "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", - "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", - "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", - "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", - "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", - "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", - "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", - "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", - "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", - "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", - "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", - "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", - "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", - "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", - "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", - "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", - "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", - "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", - "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", - "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", - "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", - "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", - "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", - "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", - "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", - "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", - "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", - "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", - "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", - "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", - "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", - "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", - "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", - "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", - "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", - "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", - "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", - "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", - "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", - "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", - "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", - "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", - "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", - "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", - "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" ], - "markers": "python_version >= '3.7'", - "version": "==2.1.5" + "markers": "python_version >= '3.9'", + "version": "==3.0.2" }, "marshmallow": { "hashes": [ - "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e", - "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9" + "sha256:ddb5c9987017d37be351c184e4e867e7bf55f7331f4da730dedad6b7af662cdd", + "sha256:efdcb656ac8788f0e3d1d938f8dc0f237bf1a99aff8f6dfbffa594981641cea0" ], - "markers": "python_version >= '3.8'", - "version": "==3.22.0" + "markers": "python_version >= '3.9'", + "version": "==3.24.1" }, "marshmallow-oneofschema": { "hashes": [ @@ -2334,11 +2345,11 @@ }, "marshmallow-utils": { "hashes": [ - "sha256:2373caa5ce1b03289cfe9f027bf1fd4e934f02a89ac4b112b1130bacc30363c6", - "sha256:412df674800031fdebbbb9ae6aba69feb3c7be3078a1a309de3f1742793f5a6e" + "sha256:20364ec5e881933f84d8dc6e84df7e74e5fb9de62568dda607b038f4fce4f531", + "sha256:7d51a0a61ba1c3f926673ea06361ec32c3d207965e7a468a63f9d000a3f3516d" ], "markers": "python_version >= '3.7'", - "version": "==0.9.2" + "version": "==0.10.0" }, "matplotlib-inline": { "hashes": [ @@ -2439,11 +2450,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" }, "mkdocs": { "hashes": [ @@ -2661,19 +2672,19 @@ }, "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": [ - "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3", - "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4" + "sha256:c83467bb5777fdfaac5ebbb8e864f300b277f68692ecc04d6dab72f2d8442344", + "sha256:e12eac052d6fd03040af4166c563d76e7aeead2e9aadf5356db552a1784bd547" ], "markers": "python_version >= '3.8'", - "version": "==7.16.4" + "version": "==7.16.5" }, "nbformat": { "hashes": [ @@ -2760,10 +2771,11 @@ }, "opensearch-py": { "hashes": [ - "sha256:5417650eba98a1c7648e502207cebf3a12beab623ffe0ebbf55f9b1b4b6e44e9", - "sha256:67ab76e9373669bc71da417096df59827c08369ac3795d5438c9a8be21cbd759" + "sha256:52c60fdb5d4dcf6cce3ee746c13b194529b0161e0f41268b98ab8f1624abe2fa", + "sha256:6598df0bc7a003294edd0ba88a331e0793acbb8c910c43edf398791e3b2eccda" ], - "version": "==2.7.1" + "markers": "python_version >= '3.8' and python_version < '4'", + "version": "==2.8.0" }, "ordered-set": { "hashes": [ @@ -2775,19 +2787,27 @@ }, "orderly-set": { "hashes": [ - "sha256:52a18b86aaf3f5d5a498bbdb27bf3253a4e5c57ab38e5b7a56fa00115cd28448", - "sha256:f7a37c95a38c01cdfe41c3ffb62925a318a2286ea0a41790c057fc802aec54da" + "sha256:571ed97c5a5fca7ddeb6b2d26c19aca896b0ed91f334d9c109edd2f265fb3017", + "sha256:d357cedcf67f4ebff0d4cbd5b0997e98eeb65dd24fdf5c990a501ae9e82c7d34" ], "markers": "python_version >= '3.8'", - "version": "==5.2.2" + "version": "==5.2.3" + }, + "outcome": { + "hashes": [ + "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", + "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.0.post0" }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" }, "pandocfilters": { "hashes": [ @@ -2830,106 +2850,97 @@ }, "pillow": { "hashes": [ - "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885", - "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea", - "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df", - "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5", - "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c", - "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d", - "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd", - "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06", - "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908", - "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a", - "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be", - "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0", - "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b", - "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80", - "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a", - "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e", - "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9", - "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696", - "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b", - "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309", - "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e", - "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab", - "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d", - "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060", - "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d", - "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d", - "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4", - "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3", - "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6", - "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb", - "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94", - "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b", - "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496", - "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0", - "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319", - "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b", - "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856", - "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef", - "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680", - "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b", - "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42", - "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e", - "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597", - "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a", - "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8", - "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3", - "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736", - "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da", - "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126", - "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd", - "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5", - "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b", - "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026", - "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b", - "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc", - "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46", - "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2", - "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c", - "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe", - "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984", - "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a", - "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70", - "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca", - "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b", - "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91", - "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3", - "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84", - "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1", - "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5", - "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be", - "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f", - "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc", - "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9", - "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e", - "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141", - "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef", - "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22", - "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27", - "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", - "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1" + "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83", + "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96", + "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", + "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", + "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", + "sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f", + "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", + "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", + "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", + "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49", + "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", + "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0", + "sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2", + "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", + "sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884", + "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e", + "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", + "sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196", + "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", + "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", + "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269", + "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", + "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb", + "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", + "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", + "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1", + "sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8", + "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90", + "sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc", + "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", + "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", + "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", + "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35", + "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", + "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", + "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2", + "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2", + "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", + "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65", + "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", + "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442", + "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2", + "sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade", + "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482", + "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", + "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", + "sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a", + "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", + "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", + "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a", + "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07", + "sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6", + "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f", + "sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e", + "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192", + "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", + "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", + "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73", + "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f", + "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6", + "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", + "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", + "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457", + "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8", + "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26", + "sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5", + "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", + "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070", + "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71", + "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", + "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761" ], - "markers": "python_version >= '3.8'", - "version": "==10.4.0" + "markers": "python_version >= '3.9'", + "version": "==11.1.0" }, "pip": { "hashes": [ - "sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2", - "sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8" + "sha256:3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", + "sha256:ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==24.2" + "version": "==24.3.1" }, "pipenv": { "hashes": [ - "sha256:422b09dc40798994a9641961983a1a4d1e831de8b91b2ad4d3d2ecb0ec42887c", - "sha256:79536f2f5be20f5101a018ca6257d4d32720d89e015691ab77bcc80bf639f2b7" + "sha256:282ac23b4a2c60cefe22bf1b747f49d55d87719d538b631e9212276920a36f68", + "sha256:87b82407a9e2de3cf32a742c131708d7460d5985076c6a9b3c11d774d2929fb1" ], "markers": "python_version >= '3.8'", - "version": "==2024.1.0" + "version": "==2024.4.0" }, "pipfile": { "hashes": [ @@ -2968,101 +2979,183 @@ "markers": "python_full_version >= '3.7.0'", "version": "==3.0.48" }, + "propcache": { + "hashes": [ + "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.9'", + "version": "==0.2.1" + }, "psycopg2": { "hashes": [ - "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981", - "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516", - "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3", - "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa", - "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a", - "sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693", - "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372", - "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e", - "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59", - "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156", - "sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024", - "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913", - "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c" + "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4", + "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11", + "sha256:47c4f9875125344f4c2b870e41b6aad585901318068acd01de93f3677a6522c2", + "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e", + "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716", + "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067", + "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442", + "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2", + "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b", + "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a" ], - "markers": "python_version >= '3.7'", - "version": "==2.9.9" + "markers": "python_version >= '3.8'", + "version": "==2.9.10" }, "psycopg2-binary": { "hashes": [ - "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9", - "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77", - "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e", - "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84", - "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3", - "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2", - "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67", - "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876", - "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152", - "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f", - "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a", - "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6", - "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503", - "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f", - "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493", - "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996", - "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f", - "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e", - "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59", - "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94", - "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7", - "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682", - "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420", - "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae", - "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291", - "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe", - "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980", - "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93", - "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692", - "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119", - "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716", - "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472", - "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b", - "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2", - "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc", - "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c", - "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5", - "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab", - "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984", - "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9", - "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf", - "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0", - "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f", - "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212", - "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb", - "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be", - "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90", - "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041", - "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7", - "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860", - "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d", - "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245", - "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27", - "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417", - "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359", - "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202", - "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0", - "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7", - "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba", - "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1", - "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd", - "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07", - "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98", - "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55", - "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d", - "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972", - "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f", - "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e", - "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26", - "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957", - "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53", - "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52" - ], - "version": "==2.9.9" + "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff", + "sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5", + "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f", + "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", + "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", + "sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c", + "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c", + "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341", + "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", + "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", + "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", + "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007", + "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", + "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92", + "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb", + "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5", + "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5", + "sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8", + "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1", + "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68", + "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", + "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1", + "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53", + "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", + "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906", + "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0", + "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", + "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a", + "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b", + "sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44", + "sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648", + "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7", + "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", + "sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa", + "sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697", + "sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d", + "sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b", + "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", + "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4", + "sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287", + "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e", + "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", + "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", + "sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30", + "sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3", + "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", + "sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92", + "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", + "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c", + "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8", + "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", + "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", + "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864", + "sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc", + "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", + "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", + "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", + "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b", + "sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481", + "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5", + "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4", + "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", + "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392", + "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4", + "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", + "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", + "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", + "sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863" + ], + "markers": "python_version >= '3.8'", + "version": "==2.9.10" }, "ptyprocess": { "hashes": [ @@ -3127,11 +3220,11 @@ }, "pygments": { "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" ], "markers": "python_version >= '3.8'", - "version": "==2.18.0" + "version": "==2.19.1" }, "pyjwt": { "extras": [ @@ -3146,17 +3239,18 @@ }, "pymdown-extensions": { "hashes": [ - "sha256:a2b28f5786e041f19cb5bb30a1c2c853668a7099da8e3dd822a5ad05f2e855e3", - "sha256:a8836e955851542fa2625d04d59fdf97125ca001377478ed5618e04f9183a59a" + "sha256:202481f716cc8250e4be8fce997781ebf7917701b59652458ee47f2401f818b5", + "sha256:741bd7c4ff961ba40b7528d32284c53bc436b8b1645e8e37c3e57770b8700a34" ], "markers": "python_version >= '3.8'", - "version": "==10.11.1" + "version": "==10.14" }, "pymysql": { "hashes": [ "sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", "sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0" ], + "markers": "python_version >= '3.7'", "version": "==1.1.1" }, "pynpm": { @@ -3169,11 +3263,11 @@ }, "pyparsing": { "hashes": [ - "sha256:4081a8e5ecf220efea188821e23de672e585e29540d3a74111fcb30b4858b838", - "sha256:d03bcc52dee87bc9783aedb2c3220f57f404d104e038005181d4222efd88ffb2" + "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", + "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a" ], "markers": "python_version >= '3.9'", - "version": "==3.2.0b3" + "version": "==3.2.1" }, "pyproject-hooks": { "hashes": [ @@ -3183,21 +3277,30 @@ "markers": "python_version >= '3.7'", "version": "==1.2.0" }, + "pysocks": { + "hashes": [ + "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299", + "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", + "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.7.1" + }, "pytest": { "hashes": [ - "sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7", - "sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], "markers": "python_version >= '3.7'", - "version": "==7.1.3" + "version": "==7.4.4" }, "pytest-cov": { "hashes": [ - "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", - "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857" + "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", + "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0" ], - "markers": "python_version >= '3.8'", - "version": "==5.0.0" + "markers": "python_version >= '3.9'", + "version": "==6.0.0" }, "pytest-flask": { "hashes": [ @@ -3217,12 +3320,12 @@ }, "pytest-invenio": { "hashes": [ - "sha256:8c40a370f8fb02087a4c1d031f2c23c54d8a1481be5e783532eb823c826a6ec2", - "sha256:b759a791c94fc79d811ad74acf795fa3b5b1293a0cd852527d537d7d40f9a180" + "sha256:8ffe0bedf4b5af95a1d6561b394eb74df5bdbe7818e30a2203e86e0e70e40b70", + "sha256:e4ab188c6780df0a740b6d88496f13e2fd51e02f475bd4c00d100f3866707a25" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.2.1" + "version": "==3.0.0" }, "pytest-isort": { "hashes": [ @@ -3234,24 +3337,24 @@ }, "pytest-pycodestyle": { "hashes": [ - "sha256:2901327b8e6beab90298a9803074483efe560e191bef81d9e18119b141222830" + "sha256:27cfebd52774ad55cceadce959913892b3b0989fc02400ef76a004a8b32ab5c9" ], - "markers": "python_version ~= '3.7'", - "version": "==2.3.1" + "markers": "python_version ~= '3.9'", + "version": "==2.4.1" }, "pytest-pydocstyle": { "hashes": [ - "sha256:a30b28d49607b2fcd7b24678ab6c4e27a288710a34b3a0f1f90f3497e88771c3" + "sha256:3770689778ad8d0de8cb51264f3d9b807c11d0ecc31f95e7025426eec126c4d2" ], - "markers": "python_version ~= '3.7'", - "version": "==2.3.2" + "markers": "python_version ~= '3.9'", + "version": "==2.4.0" }, "python-dateutil": { "hashes": [ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.9.0.post0" }, "python-dotenv": { @@ -3272,12 +3375,12 @@ }, "python-iso639": { "hashes": [ - "sha256:27526a84cebc4c4d53fea9d1ebbc7209c8d279bebaa343e6765a1fc8780565ab", - "sha256:97e63b5603e085c6a56a12a95740010e75d9134e0aab767e0978b53fd8824f13" + "sha256:02d3ce2e01c6896b30b9cbbd3e1c8ee0d7221250b5d63ea9803e0d2a81fd1047", + "sha256:750f21b6a0bc6baa24253a3d8aae92b582bf93aa40988361cd96852c2c6d9a52" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==2024.4.27" + "version": "==2024.10.22" }, "python-slugify": { "hashes": [ @@ -3305,18 +3408,18 @@ }, "pytz": { "hashes": [ - "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", - "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725" + "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", + "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" ], - "version": "==2024.2" + "version": "==2024.1" }, "pywebpack": { "hashes": [ - "sha256:1fdd5f5582eed1bd211bc890b42fffd4f8a90000ec0697f42c5182ce0839f800", - "sha256:abb44d8f20797eb33c00415de523f32beeadd72310839af7b31c65e347d91178" + "sha256:d7ce2b0ce41ecd2809ae3cc7f8c4a8f927cf9f96da1340cd7e80b6b1dc5b55f9", + "sha256:ecc6b731db3b9448822ecb236923912379782dd81c6a3fba7cae8fa368b8db6c" ], "markers": "python_version >= '3.7'", - "version": "==2.0.1" + "version": "==2.1.0" }, "pyyaml": { "hashes": [ @@ -3502,11 +3605,11 @@ }, "redis": { "hashes": [ - "sha256:b756df1e4a3858fcc0ef861f3fc53623a96c41e2b1f5304e09e0fe758d333d40", - "sha256:fd4fccba0d7f6aa48c58a78d76ddb4afc698f5da4a2c1d03d916e4fd7ab88cdd" + "sha256:d05d634b6f75a971ab3481f00c051990ee8ae5c6eb9a9e993aec0d740905f3ed", + "sha256:e8be754fdb61a95e4e7c43c4ad9fb94b1c4b407623a3bfaaf6c5f53ffb5a46cc" ], "markers": "python_version >= '3.8'", - "version": "==5.1.0" + "version": "==5.3.0b4" }, "referencing": { "hashes": [ @@ -3518,103 +3621,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": [ @@ -3642,112 +3745,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" }, "s3fs": { "hashes": [ @@ -3759,19 +3862,20 @@ }, "s3transfer": { "hashes": [ - "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6", - "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69" + "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", + "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7" ], "markers": "python_version >= '3.8'", - "version": "==0.10.2" + "version": "==0.10.4" }, "selenium": { "hashes": [ - "sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c", - "sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d" + "sha256:5296c425a75ff1b44d0d5199042b36a6d1ef76c04fb775b97b40be739a9caae2", + "sha256:b89b1f62b5cfe8025868556fe82360d6b649d464f75d2655cb966c8f8447ea18" ], "index": "pypi", - "version": "==3.141.0" + "markers": "python_version >= '3.8'", + "version": "==4.27.1" }, "sentry-sdk": { "extras": [ @@ -3785,11 +3889,11 @@ }, "setuptools": { "hashes": [ - "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2", - "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538" + "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183", + "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f" ], - "markers": "python_version >= '3.8'", - "version": "==75.1.0" + "markers": "python_version >= '3.9'", + "version": "==75.7.0" }, "simplejson": { "hashes": [ @@ -3904,7 +4008,7 @@ "sha256:fc3dc9fb413fc34c396f52f4c87de18d0bd5023804afa8ab5cc224deeb6a9900", "sha256:ff7bc1bbdaa3e487c9469128bf39408e91f5573901cb852e03af378d3582c52d" ], - "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.5' and python_version not in '3.0, 3.1, 3.2'", "version": "==3.19.3" }, "simplekv": { @@ -3917,11 +4021,19 @@ }, "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, 3.3'", - "version": "==1.16.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.17.0" + }, + "sniffio": { + "hashes": [ + "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", + "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" + ], + "markers": "python_version >= '3.7'", + "version": "==1.3.1" }, "snowballstemmer": { "hashes": [ @@ -3930,6 +4042,13 @@ ], "version": "==2.2.0" }, + "sortedcontainers": { + "hashes": [ + "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", + "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0" + ], + "version": "==2.4.0" + }, "soupsieve": { "hashes": [ "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", @@ -4098,11 +4217,11 @@ }, "termcolor": { "hashes": [ - "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63", - "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a" + "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", + "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f" ], - "markers": "python_version >= '3.8'", - "version": "==2.4.0" + "markers": "python_version >= '3.9'", + "version": "==2.5.0" }, "text-unidecode": { "hashes": [ @@ -4121,11 +4240,11 @@ }, "tinycss2": { "hashes": [ - "sha256:152f9acabd296a8375fbca5b84c961ff95971fcfc32e79550c8df8e29118c54d", - "sha256:54a8dbdffb334d536851be0226030e9505965bb2f30f21a4a82c55fb2a80fae7" + "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", + "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.4.0" }, "titlecase": { "hashes": [ @@ -4140,42 +4259,72 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.10.2" }, "tomli": { "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", + "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" + "markers": "python_version >= '3.8'", + "version": "==2.2.1" }, "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:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd", - "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad" + "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", + "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==4.66.5" + "version": "==4.67.1" }, "traitlets": { "hashes": [ @@ -4185,21 +4334,37 @@ "markers": "python_version >= '3.8'", "version": "==5.14.3" }, + "trio": { + "hashes": [ + "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05", + "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94" + ], + "markers": "python_version >= '3.9'", + "version": "==0.28.0" + }, + "trio-websocket": { + "hashes": [ + "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f", + "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638" + ], + "markers": "python_version >= '3.7'", + "version": "==0.11.1" + }, "types-beautifulsoup4": { "hashes": [ - "sha256:32f5ac48514b488f15241afdd7d2f73f0baf3c54e874e23b66708503dd288489", - "sha256:8d023b86530922070417a1d4c4d91678ab0ff2439b3b2b2cffa3b628b49ebab1" + "sha256:158370d08d0cd448bd11b132a50ff5279237a5d4b5837beba074de152a513059", + "sha256:c95e66ce15a4f5f0835f7fbc5cd886321ae8294f977c495424eaf4225307fd30" ], "markers": "python_version >= '3.8'", - "version": "==4.12.0.20240907" + "version": "==4.12.0.20241020" }, "types-bleach": { "hashes": [ - "sha256:2ee858a84fb06fc2225ff56ba2f7f6c88b65638659efae0d7bfd6b24a1b5a524", - "sha256:399bc59bfd20a36a56595f13f805e56c8a08e5a5c07903e5cf6fafb5a5107dd4" + "sha256:c6e58b3646665ca7c6b29890375390f4569e84f0cf5c171e0fe1ddb71a7be86a", + "sha256:dac5fe9015173514da3ac810c1a935619a3ccbcc5d66c4cbf4707eac00539057" ], "markers": "python_version >= '3.8'", - "version": "==6.1.0.20240331" + "version": "==6.2.0.20241123" }, "types-dateparser": { "hashes": [ @@ -4211,27 +4376,27 @@ }, "types-html5lib": { "hashes": [ - "sha256:575c4fd84ba8eeeaa8520c7e4c7042b7791f5ec3e9c0a5d5c418124c42d9e7e4", - "sha256:8060dc98baf63d6796a765bbbc809fff9f7a383f6e3a9add526f814c086545ef" + "sha256:3f1e064d9ed2c289001ae6392c84c93833abb0816165c6ff0abfc304a779f403", + "sha256:98042555ff78d9e3a51c77c918b1041acbb7eb6c405408d8a9e150ff5beccafa" ], "markers": "python_version >= '3.8'", - "version": "==1.1.11.20240806" + "version": "==1.1.11.20241018" }, "types-python-dateutil": { "hashes": [ - "sha256:27c8cc2d058ccb14946eebcaaa503088f4f6dbc4fb6093d3d456a49aef2753f6", - "sha256:9706c3b68284c25adffc47319ecc7947e5bb86b3773f843c73906fd598bc176e" + "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", + "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53" ], "markers": "python_version >= '3.8'", - "version": "==2.9.0.20240906" + "version": "==2.9.0.20241206" }, "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": [ @@ -4281,10 +4446,18 @@ }, "ua-parser": { "hashes": [ - "sha256:9d94ac3a80bcb0166823956a779186c746b50ea4c9fd9bf30fdb758553c38950", - "sha256:db51f1b59bfaa82ed9e2a1d99a54d3e4153dddf99ac1435d51828165422e624e" + "sha256:5b31133606a781f56692caa11a9671a9f330c22604b3c4957a7ba18c152212d0", + "sha256:a9740f53f4fbb72b7a03d304cae32a2785cafc55e8207efb74877bba17c35324" ], - "version": "==0.18.0" + "markers": "python_version >= '3.9'", + "version": "==1.0.0" + }, + "ua-parser-builtins": { + "hashes": [ + "sha256:1be9716c3c5994d560ea3b71261985f766ab0dfe90bdec74490304c87f1df3aa" + ], + "markers": "python_version >= '3.9'", + "version": "==0.19.0.dev30" }, "unidecode": { "hashes": [ @@ -4312,6 +4485,9 @@ "version": "==4.0.3" }, "urllib3": { + "extras": [ + "socks" + ], "hashes": [ "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32" @@ -4321,10 +4497,10 @@ }, "uwsgi": { "hashes": [ - "sha256:3ee5bfb7e6e9c93478c22aa8183eef35b95a2d5b14cca16172e67f135565c458" + "sha256:79ca1891ef2df14508ab0471ee8c0eb94bd2d51d03f32f90c4bbe557ab1e99d0" ], "index": "pypi", - "version": "==2.0.27" + "version": "==2.0.28" }, "uwsgi-tools": { "hashes": [ @@ -4359,11 +4535,11 @@ }, "virtualenv": { "hashes": [ - "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48", - "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2" + "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb", + "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329" ], - "markers": "python_version >= '3.7'", - "version": "==20.26.6" + "markers": "python_version >= '3.8'", + "version": "==20.28.1" }, "wand": { "hashes": [ @@ -4428,6 +4604,14 @@ ], "version": "==0.5.1" }, + "websocket-client": { + "hashes": [ + "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", + "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da" + ], + "markers": "python_version >= '3.8'", + "version": "==1.8.0" + }, "werkzeug": { "hashes": [ "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe", @@ -4438,86 +4622,90 @@ }, "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" + }, + "wsproto": { + "hashes": [ + "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", + "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==1.2.0" }, "wtforms": { "hashes": [ - "sha256:7b504fc724d0d1d4d5d5c114e778ec88c37ea53144683e084215eed5155ada4c", - "sha256:81195de0ac94fbc8368abbaf9197b88c4f3ffd6c2719b5bf5fc9da744f3d829c" + "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", + "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9" ], - "version": "==2.3.3" + "markers": "python_version >= '3.8'", + "version": "==3.1.2" }, "wtforms-alchemy": { "hashes": [ @@ -4528,9 +4716,11 @@ }, "wtforms-components": { "hashes": [ - "sha256:7d0d83dec6d5352c661e522be628f49c2de3aa78cd79c9caf0c1cc3bff4e3872" + "sha256:605762c32588a915b6411628d082799c6c741134fb961244a9bd8ed1686aef74", + "sha256:ca94d60a6362c0e4b49d3d09d1eb1ddf5b26c99105a57397af313655f4447f7a" ], - "version": "==0.10.5" + "markers": "python_version >= '3.9'", + "version": "==0.11.0" }, "xmlsec": { "hashes": [ @@ -4561,255 +4751,271 @@ }, "yarl": { "hashes": [ - "sha256:08d7148ff11cb8e886d86dadbfd2e466a76d5dd38c7ea8ebd9b0e07946e76e4b", - "sha256:098b870c18f1341786f290b4d699504e18f1cd050ed179af8123fd8232513424", - "sha256:11b3ca8b42a024513adce810385fcabdd682772411d95bbbda3b9ed1a4257644", - "sha256:1891d69a6ba16e89473909665cd355d783a8a31bc84720902c5911dbb6373465", - "sha256:1bbb418f46c7f7355084833051701b2301092e4611d9e392360c3ba2e3e69f88", - "sha256:1d0828e17fa701b557c6eaed5edbd9098eb62d8838344486248489ff233998b8", - "sha256:1d8e3ca29f643dd121f264a7c89f329f0fcb2e4461833f02de6e39fef80f89da", - "sha256:1fa56f34b2236f5192cb5fceba7bbb09620e5337e0b6dfe2ea0ddbd19dd5b154", - "sha256:216a6785f296169ed52cd7dcdc2612f82c20f8c9634bf7446327f50398732a51", - "sha256:22b739f99c7e4787922903f27a892744189482125cc7b95b747f04dd5c83aa9f", - "sha256:2430cf996113abe5aee387d39ee19529327205cda975d2b82c0e7e96e5fdabdc", - "sha256:269c201bbc01d2cbba5b86997a1e0f73ba5e2f471cfa6e226bcaa7fd664b598d", - "sha256:298c1eecfd3257aa16c0cb0bdffb54411e3e831351cd69e6b0739be16b1bdaa8", - "sha256:2a93a4557f7fc74a38ca5a404abb443a242217b91cd0c4840b1ebedaad8919d4", - "sha256:2b2442a415a5f4c55ced0fade7b72123210d579f7d950e0b5527fc598866e62c", - "sha256:2db874dd1d22d4c2c657807562411ffdfabec38ce4c5ce48b4c654be552759dc", - "sha256:309c104ecf67626c033845b860d31594a41343766a46fa58c3309c538a1e22b2", - "sha256:31497aefd68036d8e31bfbacef915826ca2e741dbb97a8d6c7eac66deda3b606", - "sha256:373f16f38721c680316a6a00ae21cc178e3a8ef43c0227f88356a24c5193abd6", - "sha256:396e59b8de7e4d59ff5507fb4322d2329865b909f29a7ed7ca37e63ade7f835c", - "sha256:3bb83a0f12701c0b91112a11148b5217617982e1e466069d0555be9b372f2734", - "sha256:3de86547c820e4f4da4606d1c8ab5765dd633189791f15247706a2eeabc783ae", - "sha256:3fdbf0418489525231723cdb6c79e7738b3cbacbaed2b750cb033e4ea208f220", - "sha256:40c6e73c03a6befb85b72da213638b8aaa80fe4136ec8691560cf98b11b8ae6e", - "sha256:44a4c40a6f84e4d5955b63462a0e2a988f8982fba245cf885ce3be7618f6aa7d", - "sha256:44b07e1690f010c3c01d353b5790ec73b2f59b4eae5b0000593199766b3f7a5c", - "sha256:45d23c4668d4925688e2ea251b53f36a498e9ea860913ce43b52d9605d3d8177", - "sha256:45f209fb4bbfe8630e3d2e2052535ca5b53d4ce2d2026bed4d0637b0416830da", - "sha256:4afdf84610ca44dcffe8b6c22c68f309aff96be55f5ea2fa31c0c225d6b83e23", - "sha256:4feaaa4742517eaceafcbe74595ed335a494c84634d33961214b278126ec1485", - "sha256:576365c9f7469e1f6124d67b001639b77113cfd05e85ce0310f5f318fd02fe85", - "sha256:5820bd4178e6a639b3ef1db8b18500a82ceab6d8b89309e121a6859f56585b05", - "sha256:5989a38ba1281e43e4663931a53fbf356f78a0325251fd6af09dd03b1d676a09", - "sha256:5a9bacedbb99685a75ad033fd4de37129449e69808e50e08034034c0bf063f99", - "sha256:5b66c87da3c6da8f8e8b648878903ca54589038a0b1e08dde2c86d9cd92d4ac9", - "sha256:5c5e32fef09ce101fe14acd0f498232b5710effe13abac14cd95de9c274e689e", - "sha256:658e8449b84b92a4373f99305de042b6bd0d19bf2080c093881e0516557474a5", - "sha256:6a2acde25be0cf9be23a8f6cbd31734536a264723fca860af3ae5e89d771cd71", - "sha256:6a5185ad722ab4dd52d5fb1f30dcc73282eb1ed494906a92d1a228d3f89607b0", - "sha256:6b7f6e699304717fdc265a7e1922561b02a93ceffdaefdc877acaf9b9f3080b8", - "sha256:703b0f584fcf157ef87816a3c0ff868e8c9f3c370009a8b23b56255885528f10", - "sha256:7055bbade838d68af73aea13f8c86588e4bcc00c2235b4b6d6edb0dbd174e246", - "sha256:78f271722423b2d4851cf1f4fa1a1c4833a128d020062721ba35e1a87154a049", - "sha256:7addd26594e588503bdef03908fc207206adac5bd90b6d4bc3e3cf33a829f57d", - "sha256:81bad32c8f8b5897c909bf3468bf601f1b855d12f53b6af0271963ee67fff0d2", - "sha256:82e692fb325013a18a5b73a4fed5a1edaa7c58144dc67ad9ef3d604eccd451ad", - "sha256:84bbcdcf393139f0abc9f642bf03f00cac31010f3034faa03224a9ef0bb74323", - "sha256:86c438ce920e089c8c2388c7dcc8ab30dfe13c09b8af3d306bcabb46a053d6f7", - "sha256:8be8cdfe20787e6a5fcbd010f8066227e2bb9058331a4eccddec6c0db2bb85b2", - "sha256:8c723c91c94a3bc8033dd2696a0f53e5d5f8496186013167bddc3fb5d9df46a3", - "sha256:8ca53632007c69ddcdefe1e8cbc3920dd88825e618153795b57e6ebcc92e752a", - "sha256:8f722f30366474a99745533cc4015b1781ee54b08de73260b2bbe13316079851", - "sha256:942c80a832a79c3707cca46bd12ab8aa58fddb34b1626d42b05aa8f0bcefc206", - "sha256:94a993f976cdcb2dc1b855d8b89b792893220db8862d1a619efa7451817c836b", - "sha256:95c6737f28069153c399d875317f226bbdea939fd48a6349a3b03da6829fb550", - "sha256:9915300fe5a0aa663c01363db37e4ae8e7c15996ebe2c6cce995e7033ff6457f", - "sha256:9a18595e6a2ee0826bf7dfdee823b6ab55c9b70e8f80f8b77c37e694288f5de1", - "sha256:9c8854b9f80693d20cec797d8e48a848c2fb273eb6f2587b57763ccba3f3bd4b", - "sha256:9cec42a20eae8bebf81e9ce23fb0d0c729fc54cf00643eb251ce7c0215ad49fe", - "sha256:9d2e1626be8712333a9f71270366f4a132f476ffbe83b689dd6dc0d114796c74", - "sha256:9d74f3c335cfe9c21ea78988e67f18eb9822f5d31f88b41aec3a1ec5ecd32da5", - "sha256:9fb4134cc6e005b99fa29dbc86f1ea0a298440ab6b07c6b3ee09232a3b48f495", - "sha256:a0ae6637b173d0c40b9c1462e12a7a2000a71a3258fa88756a34c7d38926911c", - "sha256:a31d21089894942f7d9a8df166b495101b7258ff11ae0abec58e32daf8088813", - "sha256:a3442c31c11088e462d44a644a454d48110f0588de830921fd201060ff19612a", - "sha256:ab9524e45ee809a083338a749af3b53cc7efec458c3ad084361c1dbf7aaf82a2", - "sha256:b1481c048fe787f65e34cb06f7d6824376d5d99f1231eae4778bbe5c3831076d", - "sha256:b8c837ab90c455f3ea8e68bee143472ee87828bff19ba19776e16ff961425b57", - "sha256:bbf2c3f04ff50f16404ce70f822cdc59760e5e2d7965905f0e700270feb2bbfc", - "sha256:bbf9c2a589be7414ac4a534d54e4517d03f1cbb142c0041191b729c2fa23f320", - "sha256:bcd5bf4132e6a8d3eb54b8d56885f3d3a38ecd7ecae8426ecf7d9673b270de43", - "sha256:c14c16831b565707149c742d87a6203eb5597f4329278446d5c0ae7a1a43928e", - "sha256:c49f3e379177f4477f929097f7ed4b0622a586b0aa40c07ac8c0f8e40659a1ac", - "sha256:c92b89bffc660f1274779cb6fbb290ec1f90d6dfe14492523a0667f10170de26", - "sha256:cd66152561632ed4b2a9192e7f8e5a1d41e28f58120b4761622e0355f0fe034c", - "sha256:cf1ad338620249f8dd6d4b6a91a69d1f265387df3697ad5dc996305cf6c26fb2", - "sha256:d07b52c8c450f9366c34aa205754355e933922c79135125541daae6cbf31c799", - "sha256:d0d12fe78dcf60efa205e9a63f395b5d343e801cf31e5e1dda0d2c1fb618073d", - "sha256:d4ee1d240b84e2f213565f0ec08caef27a0e657d4c42859809155cf3a29d1735", - "sha256:d959fe96e5c2712c1876d69af0507d98f0b0e8d81bee14cfb3f6737470205419", - "sha256:dcaef817e13eafa547cdfdc5284fe77970b891f731266545aae08d6cce52161e", - "sha256:df4e82e68f43a07735ae70a2d84c0353e58e20add20ec0af611f32cd5ba43fb4", - "sha256:ec8cfe2295f3e5e44c51f57272afbd69414ae629ec7c6b27f5a410efc78b70a0", - "sha256:ec9dd328016d8d25702a24ee274932aebf6be9787ed1c28d021945d264235b3c", - "sha256:ef9b85fa1bc91c4db24407e7c4da93a5822a73dd4513d67b454ca7064e8dc6a3", - "sha256:f3bf60444269345d712838bb11cc4eadaf51ff1a364ae39ce87a5ca8ad3bb2c8", - "sha256:f452cc1436151387d3d50533523291d5f77c6bc7913c116eb985304abdbd9ec9", - "sha256:f7917697bcaa3bc3e83db91aa3a0e448bf5cde43c84b7fc1ae2427d2417c0224", - "sha256:f90575e9fe3aae2c1e686393a9689c724cd00045275407f71771ae5d690ccf38", - "sha256:fb382fd7b4377363cc9f13ba7c819c3c78ed97c36a82f16f3f92f108c787cbbf", - "sha256:fb9f59f3848edf186a76446eb8bcf4c900fe147cb756fbbd730ef43b2e67c6a7", - "sha256:fc2931ac9ce9c61c9968989ec831d3a5e6fcaaff9474e7cfa8de80b7aff5a093" + "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.8'", - "version": "==1.13.1" + "markers": "python_version >= '3.9'", + "version": "==1.18.3" }, "zipp": { "hashes": [ - "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", - "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29" + "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", + "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931" ], - "markers": "python_version >= '3.8'", - "version": "==3.20.2" + "markers": "python_version >= '3.9'", + "version": "==3.21.0" }, "zipstream-ng": { "hashes": [ - "sha256:d5a30ac73ae70ce32e1bde937da6839f01cad1f4effeedda5bfa08c6f6b8f73d", - "sha256:f92023b9ca578cd7fdd94ec733c65664ecf7ee32493e38cdf8e365a1316e9ffc" + "sha256:b7129d2c15d26934b3e1cb22256593b6bdbd03c553c26f4199a5bf05110642bc", + "sha256:e7196cb845cf924ed12e7a3b38404ef9e82a5a699801295f5f4cf601449e2bf6" ], "markers": "python_full_version >= '3.5.0'", - "version": "==1.7.1" + "version": "==1.8.0" } }, "develop": { + "alabaster": { + "hashes": [ + "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", + "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92" + ], + "markers": "python_version >= '3.9'", + "version": "==0.7.16" + }, "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": [ + "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", + "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316" + ], + "markers": "python_version >= '3.8'", + "version": "==2.16.0" + }, + "beautifulsoup4": { + "hashes": [ + "sha256:237484d61be5d1e82b5aedd8568eea763b76191ee146597b1d405e28dbd9f3d9", + "sha256:4970105b2620a2fa530de34c76a9063c8f22d393f639d718d939f0750cc4473d" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==4.13.0b3" }, "build": { "hashes": [ - "sha256:119b2fb462adef986483438377a13b2f42064a2a3a4161f24a0cca698a07ac8c", - "sha256:277ccc71619d98afdd841a0e96ac9fe1593b823af481d3b0cea748e8894e0613" + "sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5", + "sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7" ], "markers": "python_version >= '3.8'", - "version": "==1.2.2" + "version": "==1.2.2.post1" }, "certifi": { "hashes": [ - "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", + "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db" ], "markers": "python_version >= '3.6'", - "version": "==2024.8.30" + "version": "==2024.12.14" }, "charset-normalizer": { "hashes": [ - "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", - "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", - "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", - "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", - "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", - "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", - "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", - "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", - "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", - "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", - "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", - "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", - "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", - "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", - "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", - "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", - "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", - "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", - "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", - "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", - "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", - "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", - "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", - "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", - "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", - "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", - "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", - "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", - "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", - "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", - "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", - "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", - "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", - "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", - "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", - "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", - "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", - "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", - "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", - "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", - "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", - "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", - "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", - "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", - "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", - "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", - "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", - "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", - "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", - "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", - "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", - "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", - "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", - "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", - "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", - "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", - "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", - "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", - "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", - "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", - "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", - "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", - "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", - "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", - "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", - "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", - "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", - "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", - "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", - "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", - "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", - "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", - "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", - "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", - "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", - "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", - "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", - "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", - "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", - "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", - "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", - "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", - "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", - "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", - "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", - "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", - "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", - "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", - "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", - "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" + "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.3.2" + "markers": "python_version >= '3.7'", + "version": "==3.4.1" }, "check-manifest": { "hashes": [ - "sha256:058cd30057714c39b96ce4d83f254fc770e3145c7b1932b5940b4e3efb5521ef", - "sha256:64a640445542cf226919657c7b78d02d9c1ca5b1c25d7e66e0e1ff325060f416" + "sha256:6ab3e3aa72a008da3314b432f4c768c9647b4d6d8032f9e1a4672a572118e48c", + "sha256:d300f9f292986aa1a30424af44eb45c5644e0a810e392e62d553b24bb3393494" ], "markers": "python_version >= '3.7'", - "version": "==0.49" + "version": "==0.50" }, "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": [ @@ -4827,14 +5033,31 @@ "markers": "python_version >= '3.8'", "version": "==0.10.1" }, + "docutils": { + "hashes": [ + "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", + "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" + ], + "markers": "python_version >= '3.7'", + "version": "==0.19" + }, "exceptiongroup": { "hashes": [ "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" ], - "markers": "python_version < '3.11'", + "markers": "python_version >= '3.7'", "version": "==1.2.2" }, + "furo": { + "hashes": [ + "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c", + "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2024.8.6" + }, "h11": { "hashes": [ "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", @@ -4860,6 +5083,14 @@ "markers": "python_version >= '3.6'", "version": "==3.10" }, + "imagesize": { + "hashes": [ + "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", + "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.4.1" + }, "importlib-metadata": { "hashes": [ "sha256:509ecb2ab77071db5137c655e24ceb3eee66e7bbc6574165d0d114d9fc4bbe68", @@ -4868,6 +5099,14 @@ "markers": "python_version >= '3.8'", "version": "==7.2.1" }, + "jinja2": { + "hashes": [ + "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", + "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.5" + }, "jsonlines": { "hashes": [ "sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74", @@ -4883,6 +5122,106 @@ ], "version": "==0.0.14" }, + "markdown-it-py": { + "hashes": [ + "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" + ], + "markers": "python_version >= '3.8'", + "version": "==3.0.0" + }, + "markupsafe": { + "hashes": [ + "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", + "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", + "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", + "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", + "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", + "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", + "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", + "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", + "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", + "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", + "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", + "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", + "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", + "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", + "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", + "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", + "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", + "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", + "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", + "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", + "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", + "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", + "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", + "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", + "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", + "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", + "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", + "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", + "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", + "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", + "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", + "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", + "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", + "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", + "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", + "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", + "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", + "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", + "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", + "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", + "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", + "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", + "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", + "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", + "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", + "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", + "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", + "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", + "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", + "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", + "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", + "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", + "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", + "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", + "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", + "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", + "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", + "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", + "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", + "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", + "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" + ], + "markers": "python_version >= '3.9'", + "version": "==3.0.2" + }, + "mdit-py-plugins": { + "hashes": [ + "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", + "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5" + ], + "markers": "python_version >= '3.8'", + "version": "==0.4.2" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "myst-parser": { + "hashes": [ + "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1", + "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.0.1" + }, "outcome": { "hashes": [ "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", @@ -4893,11 +5232,19 @@ }, "packaging": { "hashes": [ - "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124" + "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" ], "markers": "python_version >= '3.8'", - "version": "==24.1" + "version": "==24.2" + }, + "pygments": { + "hashes": [ + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" + ], + "markers": "python_version >= '3.8'", + "version": "==2.19.1" }, "pyproject-hooks": { "hashes": [ @@ -4913,8 +5260,68 @@ "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.7.1" }, + "pyyaml": { + "hashes": [ + "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", + "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", + "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", + "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", + "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", + "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", + "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", + "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", + "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", + "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", + "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a", + "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", + "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", + "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", + "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", + "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", + "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", + "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a", + "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", + "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", + "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", + "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", + "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", + "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", + "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", + "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", + "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", + "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", + "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", + "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706", + "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", + "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", + "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", + "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083", + "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", + "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", + "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", + "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", + "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", + "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", + "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", + "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", + "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", + "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", + "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5", + "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d", + "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", + "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", + "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", + "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", + "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", + "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", + "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.2" + }, "requests": { "hashes": [ "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", @@ -4934,27 +5341,28 @@ }, "selenium": { "hashes": [ - "sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c", - "sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d" + "sha256:5296c425a75ff1b44d0d5199042b36a6d1ef76c04fb775b97b40be739a9caae2", + "sha256:b89b1f62b5cfe8025868556fe82360d6b649d464f75d2655cb966c8f8447ea18" ], "index": "pypi", - "version": "==3.141.0" + "markers": "python_version >= '3.8'", + "version": "==4.27.1" }, "setuptools": { "hashes": [ - "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2", - "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538" + "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183", + "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f" ], - "markers": "python_version >= '3.8'", - "version": "==75.1.0" + "markers": "python_version >= '3.9'", + "version": "==75.7.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, 3.3'", - "version": "==1.16.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.17.0" }, "sniffio": { "hashes": [ @@ -4964,6 +5372,13 @@ "markers": "python_version >= '3.7'", "version": "==1.3.1" }, + "snowballstemmer": { + "hashes": [ + "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", + "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a" + ], + "version": "==2.2.0" + }, "sortedcontainers": { "hashes": [ "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", @@ -4971,6 +5386,78 @@ ], "version": "==2.4.0" }, + "soupsieve": { + "hashes": [ + "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", + "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9" + ], + "markers": "python_version >= '3.8'", + "version": "==2.6" + }, + "sphinx": { + "hashes": [ + "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3", + "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc" + ], + "markers": "python_version >= '3.9'", + "version": "==7.3.7" + }, + "sphinx-basic-ng": { + "hashes": [ + "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", + "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b" + ], + "markers": "python_version >= '3.7'", + "version": "==1.0.0b2" + }, + "sphinxcontrib-applehelp": { + "hashes": [ + "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", + "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5" + ], + "markers": "python_version >= '3.9'", + "version": "==2.0.0" + }, + "sphinxcontrib-devhelp": { + "hashes": [ + "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", + "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2" + ], + "markers": "python_version >= '3.9'", + "version": "==2.0.0" + }, + "sphinxcontrib-htmlhelp": { + "hashes": [ + "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", + "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9" + ], + "markers": "python_version >= '3.9'", + "version": "==2.1.0" + }, + "sphinxcontrib-jsmath": { + "hashes": [ + "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", + "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.1" + }, + "sphinxcontrib-qthelp": { + "hashes": [ + "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", + "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb" + ], + "markers": "python_version >= '3.9'", + "version": "==2.0.0" + }, + "sphinxcontrib-serializinghtml": { + "hashes": [ + "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", + "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d" + ], + "markers": "python_version >= '3.9'", + "version": "==2.0.0" + }, "spinners": { "hashes": [ "sha256:1eb6aeb4781d72ab42ed8a01dcf20f3002bf50740d7154d12fb8c9769bf9e27f", @@ -4980,27 +5467,57 @@ }, "termcolor": { "hashes": [ - "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63", - "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a" + "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", + "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f" ], - "markers": "python_version >= '3.8'", - "version": "==2.4.0" + "markers": "python_version >= '3.9'", + "version": "==2.5.0" }, "tomli": { "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", + "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" + "markers": "python_version >= '3.8'", + "version": "==2.2.1" }, "trio": { "hashes": [ - "sha256:0346c3852c15e5c7d40ea15972c4805689ef2cb8b5206f794c9c19450119f3a4", - "sha256:c5237e8133eb0a1d72f09a971a55c28ebe69e351c783fc64bc37db8db8bbe1d0" + "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05", + "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94" ], - "markers": "python_version >= '3.8'", - "version": "==0.26.2" + "markers": "python_version >= '3.9'", + "version": "==0.28.0" }, "trio-websocket": { "hashes": [ @@ -5019,6 +5536,9 @@ "version": "==4.12.2" }, "urllib3": { + "extras": [ + "socks" + ], "hashes": [ "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e", "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32" @@ -5044,11 +5564,11 @@ }, "zipp": { "hashes": [ - "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", - "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29" + "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", + "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931" ], - "markers": "python_version >= '3.8'", - "version": "==3.20.2" + "markers": "python_version >= '3.9'", + "version": "==3.21.0" } } } From a7231f3978d982c1ddeda0e7c2151ed411f143c8 Mon Sep 17 00:00:00 2001 From: Ian Scott Date: Thu, 9 Jan 2025 11:19:43 -0500 Subject: [PATCH 2/3] fix(upload-form): Fixed sort order bug in upload form collection selector modal --- site/kcworks/dependencies/invenio-modular-deposit-form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/kcworks/dependencies/invenio-modular-deposit-form b/site/kcworks/dependencies/invenio-modular-deposit-form index eecf74c48..a516077f3 160000 --- a/site/kcworks/dependencies/invenio-modular-deposit-form +++ b/site/kcworks/dependencies/invenio-modular-deposit-form @@ -1 +1 @@ -Subproject commit eecf74c48fe14059383035619c5976577235c264 +Subproject commit a516077f3add3bc5f259b3f3d7768a65fde77e11 From 8c8fd4cb47a06d0b84f7c7fcae5f3c65c0289c9d Mon Sep 17 00:00:00 2001 From: Ian Scott Date: Thu, 9 Jan 2025 11:20:30 -0500 Subject: [PATCH 3/3] fix(docs): Adding sphinx-generated documentation and workflow for github pages; more documentation of cli, metadata, installation, version control --- .github/workflows/documentation.yml | 31 + .gitmodules | 24 +- CHANGES.md | 1 - README.md | 745 +---------- docs/Makefile | 20 + docs/build/.buildinfo | 4 + docs/build/.doctrees/CHANGES.doctree | Bin 0 -> 24304 bytes docs/build/.doctrees/README.doctree | Bin 0 -> 3860 bytes docs/build/.doctrees/cli_commands.doctree | Bin 0 -> 20369 bytes docs/build/.doctrees/configuration.doctree | Bin 0 -> 2824 bytes docs/build/.doctrees/customizations.doctree | Bin 0 -> 92359 bytes docs/build/.doctrees/developing.doctree | Bin 0 -> 56148 bytes docs/build/.doctrees/environment.pickle | Bin 0 -> 608965 bytes docs/build/.doctrees/in_depth.doctree | Bin 0 -> 64449 bytes docs/build/.doctrees/index.doctree | Bin 0 -> 5326 bytes docs/build/.doctrees/infrastructure.doctree | Bin 0 -> 2805 bytes docs/build/.doctrees/installation.doctree | Bin 0 -> 28372 bytes docs/build/.doctrees/metadata.doctree | Bin 0 -> 95397 bytes docs/build/.doctrees/reference.doctree | Bin 0 -> 3535 bytes docs/build/CHANGES.html | 461 +++++++ docs/build/README.html | 336 +++++ .../build/_sources/CHANGES.md.txt | 0 docs/build/_sources/README.md.txt | 9 + docs/build/_sources/cli_commands.md.txt | 63 + docs/build/_sources/configuration.md.txt | 1 + docs/build/_sources/customizations.md.txt | 622 +++++++++ docs/build/_sources/developing.md.txt | 259 ++++ docs/build/_sources/in_depth.md.txt | 348 +++++ docs/build/_sources/index.rst.txt | 30 + docs/build/_sources/infrastructure.md.txt | 1 + docs/build/_sources/installation.md.txt | 121 ++ docs/build/_sources/metadata.md.txt | 807 ++++++++++++ docs/build/_sources/reference.md.txt | 5 + docs/build/_static/alabaster.css | 708 +++++++++++ docs/build/_static/basic.css | 925 ++++++++++++++ docs/build/_static/custom.css | 1 + docs/build/_static/debug.css | 69 + docs/build/_static/doctools.js | 156 +++ docs/build/_static/documentation_options.js | 13 + docs/build/_static/file.png | Bin 0 -> 286 bytes docs/build/_static/language_data.js | 199 +++ docs/build/_static/minus.png | Bin 0 -> 90 bytes docs/build/_static/plus.png | Bin 0 -> 90 bytes docs/build/_static/pygments.css | 258 ++++ docs/build/_static/scripts/furo-extensions.js | 0 docs/build/_static/scripts/furo.js | 3 + .../build/_static/scripts/furo.js.LICENSE.txt | 7 + docs/build/_static/scripts/furo.js.map | 1 + docs/build/_static/searchtools.js | 619 +++++++++ docs/build/_static/skeleton.css | 296 +++++ docs/build/_static/sphinx_highlight.js | 154 +++ docs/build/_static/styles/furo-extensions.css | 2 + .../_static/styles/furo-extensions.css.map | 1 + docs/build/_static/styles/furo.css | 2 + docs/build/_static/styles/furo.css.map | 1 + docs/build/cli_commands.html | 402 ++++++ docs/build/configuration.html | 311 +++++ docs/build/customizations.html | 1002 +++++++++++++++ docs/build/developing.html | 604 +++++++++ docs/build/doctrees/README.doctree | Bin 0 -> 3860 bytes docs/build/doctrees/cli_commands.doctree | Bin 0 -> 20401 bytes docs/build/doctrees/configuration.doctree | Bin 0 -> 2856 bytes docs/build/doctrees/customizations.doctree | Bin 0 -> 92391 bytes docs/build/doctrees/developing.doctree | Bin 0 -> 37551 bytes docs/build/doctrees/environment.pickle | Bin 0 -> 386048 bytes docs/build/doctrees/in_depth.doctree | Bin 0 -> 63922 bytes docs/build/doctrees/index.doctree | Bin 0 -> 5295 bytes docs/build/doctrees/infrastructure.doctree | Bin 0 -> 2805 bytes docs/build/doctrees/installation.doctree | Bin 0 -> 26819 bytes docs/build/doctrees/reference.doctree | Bin 0 -> 3535 bytes docs/build/genindex.html | 288 +++++ docs/build/in_depth.html | 708 +++++++++++ docs/build/index.html | 382 ++++++ docs/build/infrastructure.html | 311 +++++ docs/build/installation.html | 475 +++++++ docs/build/metadata.html | 1124 +++++++++++++++++ docs/build/objects.inv | Bin 0 -> 4939 bytes docs/build/reference.html | 326 +++++ docs/build/search.html | 299 +++++ docs/build/searchindex.js | 1 + docs/make.bat | 35 + docs/source/README.md | 9 + docs/source/changelog.md | 80 ++ docs/source/cli_commands.md | 63 + docs/source/conf.py | 29 + docs/source/configuration.md | 1 + docs/source/customizations.md | 622 +++++++++ docs/source/developing.md | 259 ++++ docs/source/in_depth.md | 348 +++++ docs/source/index.rst | 30 + docs/source/infrastructure.md | 1 + docs/source/installation.md | 121 ++ docs/source/metadata.md | 880 +++++++++++++ docs/source/reference.md | 5 + invenio.cfg | 14 +- site/kcworks/__init__.py | 2 +- .../hclegacy_metadata_fields.py | 4 +- site/pyproject.toml | 2 +- 98 files changed, 15282 insertions(+), 759 deletions(-) create mode 100644 .github/workflows/documentation.yml delete mode 120000 CHANGES.md create mode 100644 docs/Makefile create mode 100644 docs/build/.buildinfo create mode 100644 docs/build/.doctrees/CHANGES.doctree create mode 100644 docs/build/.doctrees/README.doctree create mode 100644 docs/build/.doctrees/cli_commands.doctree create mode 100644 docs/build/.doctrees/configuration.doctree create mode 100644 docs/build/.doctrees/customizations.doctree create mode 100644 docs/build/.doctrees/developing.doctree create mode 100644 docs/build/.doctrees/environment.pickle create mode 100644 docs/build/.doctrees/in_depth.doctree create mode 100644 docs/build/.doctrees/index.doctree create mode 100644 docs/build/.doctrees/infrastructure.doctree create mode 100644 docs/build/.doctrees/installation.doctree create mode 100644 docs/build/.doctrees/metadata.doctree create mode 100644 docs/build/.doctrees/reference.doctree create mode 100644 docs/build/CHANGES.html create mode 100644 docs/build/README.html rename site/CHANGES.md => docs/build/_sources/CHANGES.md.txt (100%) create mode 100644 docs/build/_sources/README.md.txt create mode 100644 docs/build/_sources/cli_commands.md.txt create mode 100644 docs/build/_sources/configuration.md.txt create mode 100644 docs/build/_sources/customizations.md.txt create mode 100644 docs/build/_sources/developing.md.txt create mode 100644 docs/build/_sources/in_depth.md.txt create mode 100644 docs/build/_sources/index.rst.txt create mode 100644 docs/build/_sources/infrastructure.md.txt create mode 100644 docs/build/_sources/installation.md.txt create mode 100644 docs/build/_sources/metadata.md.txt create mode 100644 docs/build/_sources/reference.md.txt create mode 100644 docs/build/_static/alabaster.css create mode 100644 docs/build/_static/basic.css create mode 100644 docs/build/_static/custom.css create mode 100644 docs/build/_static/debug.css create mode 100644 docs/build/_static/doctools.js create mode 100644 docs/build/_static/documentation_options.js create mode 100644 docs/build/_static/file.png create mode 100644 docs/build/_static/language_data.js create mode 100644 docs/build/_static/minus.png create mode 100644 docs/build/_static/plus.png create mode 100644 docs/build/_static/pygments.css create mode 100644 docs/build/_static/scripts/furo-extensions.js create mode 100644 docs/build/_static/scripts/furo.js create mode 100644 docs/build/_static/scripts/furo.js.LICENSE.txt create mode 100644 docs/build/_static/scripts/furo.js.map create mode 100644 docs/build/_static/searchtools.js create mode 100644 docs/build/_static/skeleton.css create mode 100644 docs/build/_static/sphinx_highlight.js create mode 100644 docs/build/_static/styles/furo-extensions.css create mode 100644 docs/build/_static/styles/furo-extensions.css.map create mode 100644 docs/build/_static/styles/furo.css create mode 100644 docs/build/_static/styles/furo.css.map create mode 100644 docs/build/cli_commands.html create mode 100644 docs/build/configuration.html create mode 100644 docs/build/customizations.html create mode 100644 docs/build/developing.html create mode 100644 docs/build/doctrees/README.doctree create mode 100644 docs/build/doctrees/cli_commands.doctree create mode 100644 docs/build/doctrees/configuration.doctree create mode 100644 docs/build/doctrees/customizations.doctree create mode 100644 docs/build/doctrees/developing.doctree create mode 100644 docs/build/doctrees/environment.pickle create mode 100644 docs/build/doctrees/in_depth.doctree create mode 100644 docs/build/doctrees/index.doctree create mode 100644 docs/build/doctrees/infrastructure.doctree create mode 100644 docs/build/doctrees/installation.doctree create mode 100644 docs/build/doctrees/reference.doctree create mode 100644 docs/build/genindex.html create mode 100644 docs/build/in_depth.html create mode 100644 docs/build/index.html create mode 100644 docs/build/infrastructure.html create mode 100644 docs/build/installation.html create mode 100644 docs/build/metadata.html create mode 100644 docs/build/objects.inv create mode 100644 docs/build/reference.html create mode 100644 docs/build/search.html create mode 100644 docs/build/searchindex.js create mode 100644 docs/make.bat create mode 100644 docs/source/README.md create mode 100644 docs/source/changelog.md create mode 100644 docs/source/cli_commands.md create mode 100644 docs/source/conf.py create mode 100644 docs/source/configuration.md create mode 100644 docs/source/customizations.md create mode 100644 docs/source/developing.md create mode 100644 docs/source/in_depth.md create mode 100644 docs/source/index.rst create mode 100644 docs/source/infrastructure.md create mode 100644 docs/source/installation.md create mode 100644 docs/source/metadata.md create mode 100644 docs/source/reference.md diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 000000000..c16ff3c01 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,31 @@ +name: Documentation + +on: + push: + branches: + - main + +permissions: + contents: write + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - name: Install dependencies + run: | + pip install sphinx furo myst-parser + - name: Sphinx build + run: | + sphinx-build docs/source docs/build + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + if: github.ref == 'refs/heads/main' + with: + publish_branch: gh_pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs/build + allow_empty_commit: true + diff --git a/.gitmodules b/.gitmodules index bd0c3fb63..836c2537b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,18 +14,6 @@ path = site/kcworks/dependencies/invenio-vocabularies url = https://github.com/MESH-Research/invenio-vocabularies.git branch = local-working -[submodule "site/kcworks/dependencies/invenio-group-collections-kcworks"] - path = site/kcworks/dependencies/invenio-group-collections-kcworks - url = https://github.com/MESH-Research/invenio-group-collections-kcworks.git - branch = main -[submodule "site/kcworks/dependencies/invenio-remote-user-data-kcworks"] - path = site/kcworks/dependencies/invenio-remote-user-data-kcworks - url = https://github.com/MESH-Research/invenio-remote-user-data-kcworks.git - branch = main -[submodule "site/kcworks/dependencies/invenio-record-importer-kcworks"] - path = site/kcworks/dependencies/invenio-record-importer-kcworks - url = https://github.com/MESH-Research/invenio-record-importer-kcworks.git - branch = main [submodule "site/kcworks/dependencies/invenio-remote-api-provisioner"] path = site/kcworks/dependencies/invenio-remote-api-provisioner url = https://github.com/MESH-Research/invenio-remote-api-provisioner.git @@ -38,3 +26,15 @@ path = site/kcworks/dependencies/invenio-modular-detail-page url = https://github.com/MESH-Research/invenio-modular-detail-page.git branch = main +[submodule "site/kcworks/dependencies/invenio-remote-user-data-kcworks"] + path = site/kcworks/dependencies/invenio-remote-user-data-kcworks + url = https://github.com/MESH-Research/invenio-remote-user-data-kcworks.git + branch = main +[submodule "site/kcworks/dependencies/invenio-group-collections-kcworks"] + path = site/kcworks/dependencies/invenio-group-collections-kcworks + url = https://github.com/MESH-Research/invenio-group-collections-kcworks.git + branch = main +[submodule "site/kcworks/dependencies/invenio-record-importer-kcworks"] + path = site/kcworks/dependencies/invenio-record-importer-kcworks + url = https://github.com/MESH-Research/invenio-record-importer-kcworks.git + branch = main diff --git a/CHANGES.md b/CHANGES.md deleted file mode 120000 index 3e111acd5..000000000 --- a/CHANGES.md +++ /dev/null @@ -1 +0,0 @@ -site/CHANGES.md \ No newline at end of file diff --git a/README.md b/README.md index 8d5fd2e3e..2eb6c8977 100644 --- a/README.md +++ b/README.md @@ -2,749 +2,12 @@ Knowledge Commons Works is a collaborative tool for storing and sharing academic research. It is part of Knowledge Commons and is built on an instance of the InvenioRDM repository system. -Version 0.3.3-beta6 +Version 0.3.4-beta7 ## Copyright -Copyright 2023-24 Mesh Research. Released under the MIT license. (See the included LICENSE.txt file.) +Copyright 2023-25 Mesh Research. Released under the MIT license. (See the included LICENSE.txt file.) -## Installation for Development +## Documentation - -### Quickstart - -These instructions allow you to run Knowledge Commons Works for local development. The app source files are copied onto your system, but the Flask application and other services (database, search, etc.) are run in Docker containers. The application is served to your browser by an nginx web server running in a separate container. - -First you will need to have the correct versions of Docker (20.10.10+ with Docker Compose 1.17.0+) and Python (3.12.0+ with pipenv). - -From there, installation involves these steps. Each one is further explained below, but here is a quick reference: - -1. Clone the git repository - 1. From your command line, navigate to the parent folder where you want the cloned repository code to live - 2. Clone the knowledge-commons-works repository with `git clone --recurse-submodules git@github.com:MESH-Research/knowledge-commons-works.git` -2. Create your configuration files - - `cd knowledge-commons-works` - - Create and configure the `.env` file in this folder as described [here](#add-and-configure-an-env-file) - - Create the `.invenio.private` file with the following contents: - ```shell - [cli] - services_setup = True - instance_path = /opt/invenio/var/instance - ``` -3. Start the docker-compose project - - `docker-compose --file docker-compose.yml up -d` -4. Initialize the database and other services, and build asset files - - enter the `web-ui` container by running `docker exec -it kcworks-ui bash` - - *note*: The container name may be different depending on your local docker setup. You can find the correct name by running `docker ps` - - run the script to set up the instance services and build static assets `bash ./scripts/setup-services.sh` - - *note*: Some of the commands in this script may take a while to run. Patience is required! The `invenio rdm-records fixtures` command in particular may take up to an hour to complete during which time it provides no feedback. Don't despair! It is working. -5. Create your own admin user - - enter the `web-ui` container by running `docker exec -it kcworks-ui bash` - - run the commands: - - `invenio users create --password ` - - `invenio users activate ` - - `invenio access allow administration-access user ` -6. View the application - - The Knowledge Commons Works app is now running at `https://localhost` - - The REST API is running at `https://localhost/api` - - pgAdmin is running at `https://localhost/pgadmin` - - OpenSearch Dashboards is running at `https://localhost:5601` - -This setup will allow you to make changes to the core Knowledge Commons Works codebase and see those changes reflected in the running application. - -### Full local development setup - -You will need to take some further steps if you want to - - Make and test changes to the various invenio modules that are included as git submodules. - - View and insert debugging statements into the code of the various core Invenio packages installed into the python environment. -To do this, you will need to do the following: - -1. In the same parent directory that holds your cloned `knowledge-commons-works` folder, clone the following additional repositories: - ```shell - git clone --single-branch -b main git@github.com:MESH-Research/invenio-record-importer-kcworks.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-groups.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-modular-deposit-form.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-modular-detail-page.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-remote-api-provisioner.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-remote-user-data-kcworks.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-communities.git - git clone --single-branch -b main git@github.com:MESH-Research/invenio-rdm-records.git - git clone --single-branch -b local-working git@github.com:MESH-Research/invenio-records-resources.git - git clone --single-branch -b local-working git@github.com:MESH-Research/invenio-vocabularies.git - ``` - The folders holding the cloned code from these repositories should then be direct siblings of your `knowledge-commons-works` folder. -2. Install the python packages required by Knowldge Commons Works locally by running `pipenv install` in the `knowledge-commons-works` folder. -3. When you start up the docker compose project, add an additional project file to the command: - - `docker-compose --file docker-compose.yml --file docker-compose.dev.yml up -d` -This will mount a variety of local package folders as bind mounts in your running containers. This will allow you to make changes to the python code in the cloned repositories and see those changes reflected in the running Knowledge Commons Works instance. - -### Controlling the KCWorks (Flask) application - -The application instance and its services can be started and stopped by starting and stopping the docker-compose project: - -```shell -docker-compose --file docker-compose.yml up -d -``` -```shell -docker-compose --file docker-compose.yml stop -``` - -> [!Caution] -> Do not use the `docker-compose down` command unless you want the containers to be destroyed. This will destroy all data in your database and all OpenSearch indices. YOU DO NOT WANT TO DO THIS! - -If you need to restart the main Flask application (e.g., after making configuration changes) you can do so either by stopping and restarting the docker-compose project or by running the following command inside the `kcworks-ui` container: - -```shell -uwsgi --reload /tmp/uwsgi_ui.pid -``` - -Similarly, the REST API can be restarted by running the following command inside the `web-ui` container: - -```shell -uwsgi --reload /tmp/uwsgi_api.pid -``` -But these commands should not be necessary in normal operation. - -## KCWorks Customizations to InvenioRDM - -### Template Customizations - -#### Page templates - -#### Email templates - -Custom email templates are located in `site/kcworks/templates/semantic-ui/invenio_notifications`. These override the default templates provided by InvenioRDM, and include both html and plaintext versions of each email, as well has markdown templates for other notification backends. - -Additional email templates are added for KCWorks-specific email types. - -- `user-first-record.create.jinja`: sent to KCWorks moderators when a user has created their first record. -- `user-first-record.publish.jinja`: sent to KCWorks moderators when a user's first record is published. - -### Record Detail Page Customizations - -#### Modular Framework (invenio-modular-detail-page) - -#### Overrides in the KCWorks Package (kcworks/site) - -### Deposit Form Customizations - -#### Modular Framework (invenio-modular-deposit-form) - -#### Overrides in the KCWorks Package (kcworks/site) - -### Collections - -#### Collections for KC Groups (invenio-group-collections-kcworks) - -### Notifications - -#### In-app notifications - -A user's unread notifications are tracked in the user's profile record. - -#### Content moderation notifications - -##### User-first-record notifications - -Emails are sent to the KCWorks moderators when a user creates their first draft and publishes their first record. This is implemented using -- a custom service component for the RDMRecord service (kcworks.services.notifications.services.FirstRecordCreatedNotificationService) that runs during draft creation and publication and - - checks whether the user has any other drafts or published records. - - if not, adds a NotificationOp to the unit of work for the record operation to emit a notification of the type "user-first-record.create" or "user-first-record.publish". -- two custom notification builder classes (kcworks.services.notifications.builders.FirstRecordPublishedNotificationBuilder and kcworks.services.notifications.builders.FirstRecordCreatedNotificationBuilder) that build the notifications. - - these builders define the notification recipients using a custom ModeratorRoleRecipient generator (kcworks.services.notifications.generators.ModeratorRoleRecipient) and sends the notification to all users with the role defined in the NOTIFICATIONS_MODERATOR_ROLE config variable. - - they also define the notification backends to be used for sending the notification. In this case, a custom EmailBackend (kcworks.services.notifications.backends.EmailBackend) that sends email via the Flask-Mail extension. -- custom email templates for the notifications, located at `site/kcworks/templates/semantic-ui/invenio_notifications/`. - -### Integrations with KC - -#### User Data Sync (invenio-remote-user-data-kcworks) - -User data is synced uni-directionally from KC to KCWorks. A user's data is synced with KC when -1. the user's SAML authentication info is first saved in KCWorks -2. the user logs into KCWorks -3. a webhook signal is received by KCWorks from KC - -#### KC Search Provisioning (invenio-remote-api-provisioner) - -#### SAML Authentication - -### Metadata Schema Customizations - -#### KCWorks Custom Fields (kcworks/site/custom_fields) - -### Bulk Record Import (invenio-record-importer-kcworks) - -### Forked Core Invenio Modules - -#### invenio-communities - -#### invenio-rdm-records - -#### invenio-records-resources - -#### invenio-vocabularies - -## KCWorks Configuration of InvenioRDM - -## KCWorks Infrastructure - -## Developing KCWorks - -### Updating the running KCWorks instance with development changes - -#### Changes to html template files - -Changes to html template files will be visible immediately in the running Knowledge Commons Works instance. You simply need to refresh the page in your browser. - -If you add a new template file (including overriding an existing template file), you will need to collect the new file into the central templates folder and restart the uwsgi processes. This can be done by running the following command inside the `web-ui` container: - -```shell -invenio collect -v -uwsgi --reload /tmp/uwsgi_ui.pid -``` -Then refresh your browser. - -#### Changes to invenio.cfg - -Changes to the invenio.cfg file will only take effect after the instance uwsgi processes are restarted. This can be done by running the following command inside the `web-ui` container: -```shell -uwsgi --reload /tmp/uwsgi_ui.pid -``` -Or you can restart the docker-compose project, which will also restart the uwsgi processes. - -#### Changes to theme (CSS) and javascript files - -##### The basic build process (slow) - -Invenio employs a build process for css and javascript files. Changes to these files will not be visible in the running Knowledge Commons Works instance until the build process is run. This can be done by running the following command inside the `web-ui` container: - -```shell -bash ./scripts/build-assets.sh -``` - -##### Rebuilding changed files on the fly (fast but limited) - -The problem is that this build process takes a long time to run, especially in the containers. For most tasks, you can instead run the following command to watch for changes to the files and automatically rebuild them: - -```shell -invenio webpack run start -``` - -The file watching will continue until you stop it with CTRL-C. It will continue to occupy the terminal window where you started it. This means that you can see it respond and begin integrating changed files when it finds them. You can also see there any error or warning output from the build process--very helpful for debugging. - -> [!Note] -> The watch command will only pick up changes to files that already existed during the last Webpack build. If you add -> - a new javascript file -> - a new css (less) file -> - a new node.js package requirement -> then you need to again run the basic (slow) build script to include it in the build process. -> After that you can run `invenio webpack run start` again to pick up changes on the fly. - -#### Adding new node.js packages to be included - -Normally, the node.js packages to be included in a project are listed in that project's package.json file. In the case of InvenioRDM, the package.json file is created dynamically by InvenioRDM each time the build process runs. So you cannot directly modify the package.json file in your instance folder. Instead, you must add the package to the package.json file in the InvenioRDM module that requires it. Unless you are creating a new stand-alone extension, this will mean adding the package to the `webpack.py` file in the `knowledge-commons-works/sites/kcworks` folder. - -There you will find a `WebpackThemeBundle` object that defines your bundle of js and style files along with their dependencies. If I wanted to add the `geopattern` package to the project, I would add it to the `dependencies` dictionary in the `WebpackThemeBundle` object like this: - -```python - -theme = WebpackThemeBundle( - __name__, - "assets", - default="semantic-ui", - themes={ - "semantic-ui": dict( - entry={ - "custom_pdf_viewer_js": "./js/invenio_custom_pdf_viewer" - "/pdfjs.js", - }, - dependencies={ - "geopattern": "^1.2.3", - }, - aliases={ - /* ... */ - }, - ), - }, -) -``` - -If you add a new node.js package to the project, you will then need to run the build script inside the `web-ui` container to install it: - -```shell -bash ./scripts/build-assets.sh -``` - -#### Changes to static files - -Changes to static files like images will require running the collect command to copy them to the central static folder. This can be done by running the following command inside the `web-ui` container: - -```shell -invenio collect -v -``` - -You will then need to restart the uwsgi processes or restart the docker-compose project as described above. - - -#### Changes to python code in the `site` folder - -Changes to python code in the `site` folder should (like changes to template files) take effect immediately in the running Knowledge Commons Works instance. You simply need to refresh the page in your browser. - -##### Adding new entry points - -Sometimes you will need to add new entry points to inform the Flask application about additional code you have provided. This is done via the `setup.py` file in the `site` folder. Once you have added the entry point declaration, you will need to re-install the `kcworks` package in the `kcworks-ui`, `kcworks-api`, and `kcworks-worker` container. This can be done by running the following command inside the each container: - -```shell -cd /opt/invenio/src/site -pip install -e . -uwsgi --reload /tmp/uwsgi_ui.pid -``` - -If you have added js, css, or static files along with the entry point code, you will also need to run the collect and webpack build commands as described above and restart the docker-compose project. - -Note that entry point changes may be overridden if you pull a more recent version of the kcworks docker image and restart the docker-compose project. Ultimately the entry point changes will have to be added to a new version of the kcworks docker image. - -#### Changes to external python modules (including Invenio modules) - -Changes to other python modules (including Invenio modules) will require rebuilding the main kcworks container. Additions to the python requirements should be added to the `Pipfile` in the kcworks folder and committed to the Github repository. You should then request that the kcworks container be rebuilt with the additions. - -In the meantime, required python packages can be installed directly in the `kcworks-ui`, `kcworks-api`, and `kcworks-worker` containers. Enter each container and then install the required package pip (not pipenv): - -```shell -pip install -``` - -### Digging deeper - -What follows is a step-by-step walk through this process. - -> [!Note] -> These instructions do not support installation under Windows. Windows users should emulate a Linux environment using WSL2. - -### Updating an Instance with Upstream Changes - -If changes have been made to the upstream Knowledge Commons Works repository and the kcworks container, you will need to update your local instance to reflect those changes. This process involves pulling the changes from the upstream repository, pulling the latest version of the kcworks docker image, restarting the docker-compose project with recreated containers, and rebuilding the asset files. - -1. First, from the root knowledge-commons-works folder, pull the changes from the upstream git repository: - -```shell -git pull origin main -``` - -2. Then pull the latest version of the kcworks docker image: - -```shell -docker pull monotasker/kcworks:latest -``` - -3. Next, restart the docker-compose project with recreated containers: - -```shell -docker-compose --file docker-compose.yml stop -docker-compose --file docker-compose.yml up -d --build --force-recreate -``` - -4. Clean up leftover containers and images: - -```shell -docker system prune -a -``` - -> [!Caution] -> Make sure that you run this `prune` command *while the containers are running.* If you run it while the containers are stopped, you will delete the containers and images that you need to run the application, as well as volumes with stored data. - -6. Rebuild the asset files with the following command: - -```shell -docker exec -it kcworks-ui bash -bash ./scripts/build-assets.sh -``` - -7. Then refresh your browser to see the changes. - -### Running automated tests (NEEDS UPDATING) - -Automated tests (unit tests and integration tests) are run every time a commit is pushed to the knowledge-commons-works Github repo. You can (and should) also run the test suite locally. - -There are currently two distinct sets of tests that have to be run separately: python tests run using invenio's fixtures, and javascript tests run separately using jest. - -#### Python tests - -The python test suite includes (a) unit tests for back end code, (b) tests of ui views and api requests run with a client fixture, (c) user interaction tests run with selenium webdriver. To run the unit tests and view/request tests, navigate to the root knowledge-commons-works folder and run -```console -pipenv run pytest -``` -By default the selenium browser interaction tests are not run. To include these, run pytest with the E2E environment variable set to "yes": -```console -pipenv run E2E=yes pytest -``` -Running the selenium tests also requires that you have the Selenium Client and Chrome Webdriver installed locally. - -#### Javascript tests - -Pytest does not directly test custom javascript files or React components. In order to test these, navigate to the root knowledge-commons-works folder and run -```console -npm run test -``` -These tests are run using the jest test runner, configured in the packages.json file in the root knowledge-commons-works folder. - -Note that these tests run using a local npm configuration in the knowledge-commons-works folder. Any packages that are normally available to InvenioRDM must be added to the local package.json configuration and will be installed in the local node_modules folder. Since this folder is not included in GIT version control, before you run the javascript tests you must ensure the required packages are installed locally by running -```console -npm install -``` - -## In-depth Development Installation Instructions (NEEDS UPDATING) - -### Install Python and Required Python Tools - -#### Ensure some version of python is installed - -Most operating systems (especially MacOS and Linux) will already have a version of Python installed. You can proceed directly to the next step. - -#### Install pyenv and pipenv - -First install the **pyenv** tool to manage python versions, and the **pipenv** tool to manage virtual environments. (There are other tools to use for virtual environment management, but InvenioRDM is built to work with pipenv.) - -Instructions for Linux, MacOS, and Windows can be found here: https://www.newline.co/courses/create-a-serverless-slackbot-with-aws-lambda-and-python/installing-python-3-and-pyenv-on-macos-windows-and-linux - -#### Install and enable Python 3.9.16 - -Invenio's command line tools require a specific python version to work reliably. Currently this is python 3.9.16. At the command line, first install this python version using pyenv: -```console -pyenv install 3.9.16 -``` -Note: It is important to use cpython. Invenio does not support other python interpreters (like pypy) and advises against using anaconda python in particular for running the RDM application. - -Just because this python version is installed does not guarantee it will be used. Next, navigate to the directory where you cloned the source code, and set the correct python version to be used locally: - -```console -cd ~/path/to/directory/knowledge-commons-works -pyenv local 3.9.16 -``` - -#### Install the invenio-cli command line tool - -From the same directory Use pip to install the **invenio-cli** python package. (Do not use pipenv yet or create a virtual environment.) - -```console -pip install invenio-cli -``` - -### Install Docker 20.10.10+ and Docker-compose 1.17.0+ - -#### Linux - -If you are using Ubuntu Linux, follow the steps for installing Docker and Docker-compose explained here: https://linux.how2shout.com/install-and-configure-docker-compose-on-ubuntu-22-04-lts-jammy/ - -You must then create a `docker` group and add the current user to it (so that you can run docker commands without sudo). This is *required* for the invenio-cli scripts to work, and it must be done for the *same user* that will run the cli commands: - -```console -sudo usermod --append --groups docker $USER -``` - -You will likely want to configure Docker to start on system boot with systemd. - -#### MacOS - -If you are using MacOS, follow the steps for installing Docker desktop explained here: https://docs.docker.com/desktop/install/mac-install/ - -You will then need to ensure Docker has enough memory to run all the InvenioRDM containers. In the Docker Desktop app, - -- click settings cog icon (top bar near right) -- set the memory slider under the "Resources" tab manually to at least 6-8GB - -Note: The environment variable recommended in the InvenioRDM documentation for MacOS 11 Big Sur is *not* necessary for newer MacOS versions. - -#### Fixing docker-compose "not found" error - -With the release of compose v2, the command syntax changed from `docker-compose` to `docker compose` (a command followed by a sub-command instead of one hyphenated command). This will break the invenio-cli scripts, which use the `docker-compose` command and you will receive an error asking you to install the "docker-compose" package. - -One solution on Linux systems is to install Docker Compose standalone, which uses the old `docker-compose` syntax: - -```console -sudo curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose -sudo chmod +x /usr/local/bin/docker-compose -``` - -Another approach is simply to alias the `docker compose` command to `docker-compose` in the configuration file for your command line shell (.bashrc, .zshrc, or whichever config file is used by your shell). - -See further https://docs.docker.com/compose/install/other/ - -#### Docker log rotation - -Regardless of your operating system, you should set up log rotation for containers to keep the size of logging files from getting out of control. Either set your default logging driver to "local" (which rotates log files automatically) or set logging configuration if you use the "json-file" logging driver. See https://docs.docker.com/config/containers/logging/configure/ - -#### Note about docker contexts - -Make sure to always use the same Docker context to run all of the containers for InvenioRDM. See further, https://docs.docker.com/engine/context/working-with-contexts/ - -### Install Node.js and NVM - -Currently InvenioRDM (v. 11) requires Node.js version 16.19.1. The best way to install and manage Node.js versions is using the nvm version manager. You can find instructions here: https://www.freecodecamp.org/news/node-version-manager-nvm-install-guide/ - -Once nvm is installed, install the required Node.js version and set it as the active version: -```console -nvm install v16.19.1 -nvm use 16.19.1 -``` -You may have other Node versions installed as well, so before a session working with Knowledge Commons Works it's a good idea to make sure you're using the correct version. On MacOS and Linux you can check -from the command line with -```console -which node -``` -### Clone the knowledge-commons-works Code - -Using GIT, clone this repository. You should then have a folder called `knowledge-commons-works` (unless you chose to name it something else) on your local computer. - -### Add and Configure an .env File - -Private environment variables (like security keys) should never be committed to version control or a repository. You must create your own file called `.env` and place it at the root level of the knowledge-commons-works folder. This is a plain text file of key value pairs, with one pair per line, following the pattern `MY_VARIABLE_NAME_IN_CAPS="my value"`. Any configuration variables to be picked up by Invenio should have the prefix "INVENIO_" added to the beginning of the variable name. Environment variables for other services (e.g., for pgadmin) should not. (These prefixes are already present in the following standard variables.) - -#### Standardized environment variables - -This file must include the following variables with these values: - -```env -INVENIO_INSTANCE_PATH=/opt/invenio/var/instance -INVENIO_RECORD_IMPORTER_LOCAL_DATA_DIR=/ -INVENIO_RECORD_IMPORTER_DATA_DIR=/opt/invenio/var/import_data -INVENIO_SEARCH_DOMAIN='search:9200' -INVENIO_SITE_UI_URL="https://localhost" -INVENIO_SITE_API_URL="https://localhost/api" -REDIS_DOMAIN='cache:6379' -INVENIO_SQLALCHEMY_DATABASE_URI="postgresql+psycopg2://kcworks:kcworks@db/kcworks" -POSTGRES_USER=kcworks -POSTGRES_DB=kcworks -``` - -The INVENIO_INSTANCE_PATH should be set to the full path of the instance directory where InvenioRDM will store its compiled files. Since KC Works runs inside containers, this is normally a standard folder inside the container file systems (/opt/invenio/var/instance). If you were to run InvenioRDM with the python/uwsgi processes installed on your local machine, this would be a folder inside your local virtual environment folder. For example, on MacOS this might be ~/.local/share/virtualenvs/{virtual env name}/var/instance/. - -#### Variables for local credentials - -Several variables hold random values used to secure the application, or hold passwords and email addresses supplied by the local developer: - -```env -INVENIO_CSRF_SECRET_SALT='..put a long random value here..' -INVENIO_SECURITY_LOGIN_SALT='..put a long random value here..' -INVENIO_SECRET_KEY=CHANGE_ME -POSTGRES_PASSWORD=??? -PGADMIN_DEFAULT_EMAIL=??? -PGADMIN_DEFAULT_PASSWORD=??? -``` - -Random values for secrets like INVENIO_SECRET_KEY can be generated in a terminal by running -```console -python -c 'import secrets; print(secrets.token_hex())' -``` -#### Additional environment variables with sensitive information - -Additionally, you should add the following variables with the appropriate values obtained from the Commons administrators: - -```env -COMMONS_API_TOKEN=mytoken # this must be obtained from the Commons administrators -COMMONS_SEARCH_API_TOKEN=mytoken # this must be obtained from the Commons administrators -INVENIO_DATACITE_PASSWORD=myinveniodatacitepassword # this must be obtained from the Commons administrators -``` -You will also need to enter the following variable with a dummy value and then replace it with the actual value after the instance is set up. Once you have an administrative user, you can generate a token for that user in the KC Works admin ui and enter it here: - -```env -API_TOKEN=myapitoken -``` - -#### Additional required environment variables with paths on your local file system - -The next variables refer to paths on your local file system that are used during local development to provide easy access to the source code of various python packages and KCWorks modules: - -```env -PYTHON_LOCAL_GIT_PACKAGES_PATH=/path/to/local/git/packages -PYTHON_LOCAL_SITE_PACKAGES_PATH=/path/to/local/virtual/environment/lib/python3.12/site-packages -``` - -PYTHON_LOCAL_GIT_PACKAGES_PATH is the parent directory that holds cloned packages that aren't available via pip or that have been forked by us. If you are not working with the KCWorks custom modules locally, this can be set to the folder where you cloned the KCWorks code. Otherwise, it should be the path to the parent folder containing the git repositories for the forked Invenio modules and the extra KC Works modules. - -PYTHON_LOCAL_SITE_PACKAGES_PATH is the path to the site-packages folder in your local virtual environment. This assumes that you have run `pipenv install --dev --python=3.12` in your KCWorks project folder to install the python packages locally in a virtual environment. - -### Install the Invenio Python Modules - -Navigate to the root knowledge-commons-works folder and run -```console -pipenv install --dev --python=3.12 -``` -Note: This installation step will take several minutes. - -This stage -- creates and initializes a Python virtual environment using pipenv -- locks the python package requirements -- installs the Invenio python packages (with pipenv) - - these packages are again installed under your virtual environment folder. On MacOS this is often ~/.local/share/virtualenvs/{virtual env name}/lib/python3.9/site-packages/. You will find several modules installed here with names that start with "invenio_". -- installs the `kcworks` Python package (with pipenv) - - alongside the Invenio packages you will also find a `kcworks` package containing any custom extensions to InvenioRDM defined in your `knowledge-commons-works/sites/` folder -- installs required python dependencies (with pipenv) - -### Build and Configure the Containerized Services - -#### Build and start the containers - -Make sure you are in the root knowledge-commons-works folder and then run -```console -docker-compose up -d -``` -This step will -- build the docker image for the nginx web server (frontend) using ./docker/nginx/Dockerfile -- pull remote images for other services: mq, search, db, cache, pgadmin, opensearch-dashboards -- start containers from all of these images and mounts local files or folders into the containers as required in the docker-compose.yml and docker-services.yml files - -#### Create and initialize the database, search indices, and task queue - -Again, from the root knowledge-commons-works folder, run this command: -```console -invenio-cli services setup -``` - -This step will -- create the postgresql database and table structure -- create Invenio admin role and assigns it superuser access -- begin indexing with OpenSearch -- create Invenio fixtures -- insert demo data into the database (unless you add the --no-demo-data flag) - -Note: If for some reason you need to run this step again, you will need to add the `--force` flag to the `docker-compose` command. This tells Invenio to destroy any existing redis cache, database, index, and task queue before recreating them all. Just be aware that performing this setup again with `--force` will **destroy all data in your database and all OpenSearch indices**. - -#### Start the uwsgi applications and celery worker - -Finally, you need to start the actual applications. Knowledge Commons Works is actually run as two separate applications: one providing an html user interface, and one providing a REST api and serving JSON responses. Each application is served to the nginx web server by its own uwsgi process. The nginx server begins automatically when the `frontend` docker container starts, but the uwsgi applications run on your local machine and need to be started directly. - -These applications are also supported by a Celery worker process. This is a task queue that (with the help of the RabbitMQ docker container) frees up the python applications from being blocked by long-running tasks like indexing. The celery worker also runs on your local machine and must be started directly. - -If you want to quickly start all of these processes in the background (as daemons), you can run the kcr-startup.sh script in the root knowledge-commons-works directory: -```console -bash kcr-startup.sh -``` -The processes will output request and error logging to files in the `logs` folder of your knowledge-commons-works folder. - -To stop these processes, simply run -```console -bash kcr-shutdown.sh -``` - -If you would like to view the real time log output of these processes, you can also start them individually in three separate terminals: -```console -pipenv run celery --app invenio_app.celery worker --beat --events --loglevel INFO -``` -```console -pipenv run uwsgi docker/uwsgi/uwsgi_ui.ini --pidfile=/tmp/kcr_ui.pid -``` -```console -pipenv run uwsgi docker/uwsgi/uwsgi_rest.ini --pidfile=/tmp/kcr_api.pid -``` -These processes can be stopped individually by pressing CTRL-C - - -#### Create an admin user - -From the command line, run these commands to create and activate the admin user: -```console -pipenv run invenio users create --password -pipenv run invenio users activate -``` -If you want this user to have access to the administration panel in Invenio, you also need to run -```console -pipenv run invenio access allow administration-access user -``` - -### Use the application! - -You should now be able to access the following: -- The Knowledge Commons Works app (https://localhost) -- The Knowledge Commons Works REST api (https://localhost/api) -- pgAdmin for database management (https://localhost/pgadmin) -- Opensearch Dashboards for managing search (https://localhost:5601) - -#### Controlling the Application Services - -Once Knowledge Commons Works is installed, you can manage its services from the command line. **Note: Unless otherwise specified, the commands below must be run from the root knowledge-commons-works folder.** - -#### Startup and shutdown scripts - -The bash script kcr-startup.sh will start - - the containerized services (if not running) - - the celery worker - - the two uwsgi processes -It will also ensure that you have a .env file and copy your set your INVENIO_INSTANCE_PATH variable in that file to your local instance folder, matching the instance_path variable in your .invenio.private file. - -Simply navigate to the root knowledge-commons-works folder and run -```console -bash ./kcr-startup.sh -``` - -To stop the processes and containerized services, simply run -```console -bash ./kcr-shutdown.sh -``` - -#### Controlling just the containerized services (postgresql, RabbitMQ, redis, pgAdmin, OpenSearch, opensearch dashboards, nginx) - -If you want to stop or start just the containerized services (rather than the local processes), you can use the invenio cli: -```console -invenio-cli services start -invenio-cli services stop -``` -Or you can control them directly with the docker-compose command: -```console -docker-compose up -d -docker-compose stop -``` -Note that stopping the containers this way will not destroy the data and configuration which live in docker volumes. Those volumes persist as long as the containers are not destroyed. **Do not use the `docker-compose down` command unless you want the containers to be destroyed.** - -#### View logging output for uwsgi processes - -Activity and error logging for the two uwsgi processes are written to date-stamped files in the knowledge-commons-works/logs/ folder. To watch the live logging output from one of these processes, open a new terminal in your knowledge-commons-works folder and run -```console -tail -f logs/uwsgi-ui-{date}.log -``` -or -```console -tail -f logs/uwsgi-api-{date}.log -``` - -#### View container logging output - -The logging output (and stdout) can be viewed with Docker Desktop using its convenient ui. It can also be viewed from the command line using: - -```console -docker logs -f -``` - -The names of the various images are: -- nginx: kcworks-frontend-1 -- RabbitMQ: kcworks-mq-1 -- PostgreSQL: kcworks-db-1 -- OpenSearch: kcworks-search-1 -- Redis: kcworks-cache-1 -- OpenSearch Dashboards: kcworks-opensearch-dashboards-1 -- pgAdmin: kcworks-pgadmin-1 - -#### Controlling containerized nginx server - -The frontend container is configured so that the configuration files in docker/nginx/ are bind mounted. This means that changes to those config files can be seen in the running container and enabled without rebuilding the container. To reload the nginx configuration, first **enter the frontend container**: -```console -docker exec -it kcworks-frontend-1 bash -``` -Then tell gninx to reload the config files: -```console -nginx -s reload -``` -You can also test the nginx config prior to reloading by running -```console -nginx -t -``` -Alternately, you can rebuild and restart the frontend container by running -```console -docker-compose up -d --build frontend -``` - -## Reference - -### InvenioRDM Documentation - -The Knowledge Commons Works is built as an instance of InvenioRDM. The InvenioRDM Documentation, including customization and development information, can be found at https://inveniordm.docs.cern.ch/. +The technical documentation, including installation instructions, lives at https://mesh-research.github.io/knowledge-commons-works/ \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..d0c3cbf10 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/build/.buildinfo b/docs/build/.buildinfo new file mode 100644 index 000000000..f97579b82 --- /dev/null +++ b/docs/build/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: c98d14472b07a7a52cb283ce05317c0a +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/.doctrees/CHANGES.doctree b/docs/build/.doctrees/CHANGES.doctree new file mode 100644 index 0000000000000000000000000000000000000000..999345a9d174083211d41644656e267091f3ce9e GIT binary patch literal 24304 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 G(*FVki;>g- literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/README.doctree b/docs/build/.doctrees/README.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4ceb6542bf0eac6e95e71ac70c160d5c1e8ace39 GIT binary patch literal 3860 zcmdT{OK%*<5tc+R$>n27N|qA9qBBO|SVGKQK~e(4Kn{ka1Hq67`jJbFLGMiOc7r|L zlkOgJc@U5s41_@6Joy3n9r-JH{Db5#F?dC zeqqn$Lh9L&rKvV4cV*a2O;TiB`|{iJ>7UBC<&)62?8=$KCcF%Hz>x^4Qp3^;%13qB*oE%}?WwqQMH z&^ckYD5-gQR*YHLV%}RhE{yQ3>(FWd+QyHRcE=={xRuTS3$v$PcNi5>A+tQBKCypIR6sb#rXbk5&ST8YuC zT4MA&k{C%Bu_!T0v9Ynt%S#@4V^lOTHgeursizUsY2*Z}*9l8`CX>i=$C*vUFgo@m z1!{d{Cee2l(RDD43#q`NAuf{Id8QLi7rfxnvA*P5n)BDEkeeGPq4_#;*Us~7Scmjc z_))*1!5>03qELy$Gx0t_O#BSE5+4AwKga(={6E6~DKH~`DUN^@u!@ftB0Q{9N%X>l zuYe!qNAzs?V))`{%su;c>#JMO<~IE1huP3uv0=Nlq0PtrmJs@{Onz5HB}d;a3+`OD~(I}x3C@I2>=Gsn}Y&?&bS+)j_bh?GpY zc6=B;`J4mu0HM^0DpD~1_W0GCv(MiQ{me%bsrc||>(>91wz;2v|NZ?$VCgUWiFfD< z{iKTvYoWGGT)^Gdg3FuAvLLF5Qh`D{7t;||M4-%7&|Rye_P?>-6<_gjc-LE0M1@jh zbevl=MWLySZ_gXgRC#hIY_&W*#kQbSxf=#aVX3soT_N9TDRn^)n~r;rf`;C7&^4Qh zHQIBXmSO!XrV3Q@wp)q4v(TS%%~2PPEwM=%8i8k7j?H$hCWh<_Y`2SkXfo zD>vF~KxXaWF%I~zQVZ<64O>h#t{PIF`UAYh)LzJ9iog;e`Csw@KfP^?miujKz76Y+6$wH#!g3Ncu1U; z0pN_$_z@nDaBPBp^x?CY@aMozk`?hpnT!8LD;}B32(K614kh=KN(XX&Bz&fztnb+v zDU^Cqo@|Cg05Xfa-0U6@yPObm6ZYM;_G}glG&WT=H%y6!aKGa+3_kH63M93IqaIZI zdK)W~u*S8A2?i*ZAngkp@PQWYNl<9zzxu25~(M^KwA~=Q=M?dc!f`9 z1YTuWor*NSUX;L0Hs&ev_ZlV$&OMYoOu%&!^NdLqV^XKuTA6*&%-R5}n$$JzCaiIN zNpo=6tZNC97f_Tsl}HXBduFE`wFxuu0gM8)Jmz;)?Ubfo8khGlwWf(Fw5RzMqci5y zpRBS+Kx-hx*cK$`j@+9VEV2Wwm3umgPIWDa4@$ele(Jd#Xq~TNIFNSq0H}K+He1H(KUOy360%;^v z5&A^+*EvE;Q{~l-FgJzxfYu(L2uhq3VRsScm8{)FB3USKkY7`%nzej&fEOt>AHt5b z$i_x>nNzX8yF%=^`%4o0t=8(&{U!P6O4d^we7GvBIl%~kT3aEDI?6VEzyOkX1Dfr| zD?%LT-@*&ul;@}$_&7lY!e^R8rql|%lDkCS?#LC`x0{&|$u%XMZ>7`~ngU8wP1wrt QkrF#qV5)dq7USW60mSpu5C8xG literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/cli_commands.doctree b/docs/build/.doctrees/cli_commands.doctree new file mode 100644 index 0000000000000000000000000000000000000000..1b0cbc231dc731447ba5308403e1da6a25d90655 GIT binary patch literal 20369 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 U*?b#^ChM`EB5QfIn{KWCABdLtk^lez literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/configuration.doctree b/docs/build/.doctrees/configuration.doctree new file mode 100644 index 0000000000000000000000000000000000000000..7aeb7e44a35b34943f2a1cae52bd220d96cd9c03 GIT binary patch literal 2824 zcmaJ@TW=gS6mFVslHDYmOD`a$fmW!LiY8kX9uTkX3yK<{3V5QjykpPWT8};0o@Db7 z2_7mD$!|5{@(gTyDmCn zMXbJwq8mD1dd082341S$&gH1GG~Ib%@(17O6RxFs{qj|u-n#W2pQLF1U-@lpf?X*o zLi17Vgf5xoB9_C-G=<}EOG(Y+aW$l&N4>XlSb3zLQeBqJrLg^Wv$5rQ(y79#r=#>LiY@Wc(URB?-wwWa+`56J+GWQ3!ApL^l_^tg2V-qc6=x%U zkeQ+|+8vx4J9YyE>;_GsgY0T)4ht5=p4brg#WDgHA0t}v5Yg?;sU4X7KsFV$tcX;6 zg2F#~Pc0RCPVF(&o*)nLx#%_Vi>Gk6yy&jAC#Dx>RTWRe9dD7Usyj(aYets4rm7up zJXP`NM(DLVoZ(m{e@mgCRW|jE%sRBuN}5iEHOIY|dIWs#%m9~LqdnIwhLs{$%ExiMZF z&#$~ZS_+#9?Yb(+BsaE*kn|k@Rg%j)HP&GSt!VaHE)XGy|xmKwYI*bpi5#04psnw_zG%TkDBwZ9e<0+~5Yv@Z| zR-SO383wHwx|PolzB+Ic&-dqF5^k-rL{QBXx2SUpHS;lSnaa;w>C{$Y*k5?FU_$&D z`i;@c0NShf=U*(`4BIIIz{?5LM12b?EyARuLzNOq`w$mb+iAdLZ6Fy3{MVy}cbii+ zl1tTWrhDlLPOx#(B1LEo;I$Dv>HlAtIYgP7F? z+enfjMeJ!Z!iU29(tSM`KIwP)ylR6^7cOP`B%Ib0o@SbXwZ|Oi;vw#y7);D%T~% z?QvDYMWVo(*rrS10_ZWB)HyKFZiU^nCtNjL(33?1uQIe5#Y9Zw2+R~i&M?1c2tjb} z;pA=xtuf&Rm5P9^({8Q9-kI_(z^d|Qr(J|)u1^xdg|%jvV0ZyVshPxZc;cxYaqK4W z!VZE0v^+Q*uwjYL5)W>Hj#y?Y?GrJ96T#jeEUHQ^7nnXQebKP?z4X*jGHB#4cZIQ9 z3VGiLZCNGJ!XIK^JVgdOmyr}w*F-J;Y(7jxCoDai`FnQh@1JY^U1RAwk5$;6OSB>U z>x=UHwc-6;rMlmCD27JOCZ$%rvml&lcjqj2Td(z{-8uVUA?p+E z-CeXbeFMtJZmp4&7-T&&N&$k%0pz;+A|VX&cS!zie2qPUuQzNQd~Z2SM&od{V&}x` pGjR>>b*VE|u{2DhgzFwlEHGV|=_@AmiZch=R29A=&SNz^{12S~Yis}j literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/customizations.doctree b/docs/build/.doctrees/customizations.doctree new file mode 100644 index 0000000000000000000000000000000000000000..f05a45acd68508b605619552f723fd81e423ab6f GIT binary patch literal 92359 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 literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/developing.doctree b/docs/build/.doctrees/developing.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4d64eba567f9e802ef7a63fe6eca25ecd762ed04 GIT binary patch literal 56148 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 Jb&|#M{|B3JtbhOj literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/environment.pickle b/docs/build/.doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..c5cb32e46151d1622924694e392885caf783141e GIT binary patch literal 608965 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
-AA z=Mdh;d4o03x>J4#P?nXGeUl0d;v1qBib);U>rIWX@f%|n=dt6OeKK3!lgXzWwaidB zF6N`wtUU+TuDY2#(u0uDSUdP|`*!@GDGS{WJ|Li&>h5X=8GOXc7T4wdnQ|3 zNQ{~Ko2GWsRrc$qEUcS)A(Ox&fx;qd?{q}3+}Py3N2!rOVNm0V$m_<|JKxU z+W5aVWnta;3)uL>nF_8PPZu)-UNL0*lr`Hg6t)+VT_HJUdI#d$^fA|%vaoLYMWWv0 zUV&0QeL7PuVF@y1{QcI9zgSj$mhJkoW9IKMwVkf{H=44rZvOeg{EceOOV{)DNJ{j) zHQO(cwkN@^5F9i7psCfg;j^YJtQ&qN89wI?RlTq$)3j#tS!{ACGG^?vrk2vieyJ%7 z>&BkT#?IHWc_alag$@3GYX+Yu46en-jQ&1Ti)o|3$CQP2qt7Cv!*`4&GyjS;i_d0@ z`!ZwZ{*tM!w7LJrl!bM3FDG-4cwQX?XgauX9U4u4Va@g{*!EHZH>5xeh@Y8SQ3LTG zrYx)j!Oo;SNZevfUH&{`Yb~1AgY$bfX&fo3gMD2Db$)vybHKG^<4zSU%hq?ze`5XbVcVD`dyaf3K4t(*P+nB}2KzOUE1vLn7Hf3QQ1n!UmT|heL zRgi*&wjo1a(dVrJAv&ah3T{A!7#N>5wWJ2))21w}gE5a<#6Y=xGL5zn4MP2iH3a5! zQy{sN7lh=-%>F}Dn`yKEvndPfW?w>Pr|t)pe-M-3T)Li#1o_Q*zAcw@DI1@pqu#T0 zm!-!bm^gGY|6qqNSj)K)Tkhe9%0Ahz|?OIrjAxHNsT4|>WHb8HBg64 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 Qq)QzQmT^V;?t#w#2Qi#;!2kdN literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/in_depth.doctree b/docs/build/.doctrees/in_depth.doctree new file mode 100644 index 0000000000000000000000000000000000000000..03d7592fc7ea02f33b1380f92786da6f26c87aad GIT binary patch literal 64449 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 H{?>m1efj(E literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/infrastructure.doctree b/docs/build/.doctrees/infrastructure.doctree new file mode 100644 index 0000000000000000000000000000000000000000..03681ef1d5f3ccb07678eeab48f1d5fd4a11fa22 GIT binary patch literal 2805 zcmZ`*TW=gS6mFVslHDYmOD`a`0V-5VMU$;69uTkP1w}*xae1M#ykqa$T8};W(rg|g z!9yh?`K?A={sH_neg&Urb~f2X=eK`*H|oE*<0>Kb^oTO14dX7w z4Q7f^a_!Tb^yHUxo<5FUOHZ8%w%{q=fJPytVwUUlGR1yY_fol|+5L6L3onhHUl$#* zCe~jj(TyE1z2aBi#CyjtelT|8KKN3PEOp+7!UxOK?82>Y`7{Uezk07z6XIG$5s*(} zFLud11F;&{W`Uo?TS{u4PQsAJ9`)YJVem*eC%7t^%gL-4iaG}&o;#YB&C>=8)#YJG zi;3lCY@rpQzUk|=>+`56J+7-t8!591$SEkAp9Za-2Rh*6aVPVSB zXm@y;lOG^pH)sMK$b~{2l`M(-VoN*_tB72@k8s69gm-UJ)OQaT^%E5zqSTMBXngRN z#$#waLHObm(QCpMPvK;B*-2|k%r4A}DW1kV-XcRqbE`>Z&De6+6tm-vrz#!ah`m;a zGaN(qw-WnBu(?%a-k7ac(ljV;IPSgFV}NmQj;@h4+H=iPT>GA?fX=k=6gwxeJLZ~O z>Wxh}Fp9={T2?r0Hf{)PPjKwbj=?INw!JAxZfJfBcOArK&r;kU8RNC_{L0JYmAIXu ztwTwsBV)@1Ngs%n70KPiRR@#z8wppumXK5F1!-XgkFyIioSnoi%PV6&Q5h!b_-5=0 zs^-T|+~ZS;T6yY&Yn3{&!}u_a;jVv5twyb&VL2@!>7wWb&q<|UV_)hjc*1pI7_?IC z20uFd?9fR(KUjQ8xV6R-K{Zp{qRu(g!l$@nf?u@KsjZ}Vu=Hlhg!nP`8>5#2v{xT2 zzF4{$cXI-OmlLRuLP9BSE2_tVjycNBaK4EJ6mMHz7|RIb6~F;E6394-YlYDx74kpgV=7${V-ls@Z9N5+l^Dc;SRbpX&Lo|kBkM>{qkKYaA;Q`EC>N5zu)EV(rQ zQEMKPN;6(3+#X5pN3{>k{6P3p!CBYSAx4OKk&ZXw0RUN&`E1S;Ag;;?xrn>&OnW*d zLXL&P58%C}Ove3|D=DVzr+}e$DAeux+#HEA1)Y`lpb!-Cpz+PHp~`g$aeERfxX650 zv)F72TmU_$z={P1+O4pk_k;_>B|TYY@G3)_QOtZaNx)1w{ca~M9mP@oASDrUKeJ?*XObivOx{c@i~!&&9ite1}=89z@Js<<#`g%FPwOY{{yk*;`UWo*SEI|iQ&kN zg2hIXw^yszH1w*Z(LWA9!&fuuFTB*Y0gZtP$?#56>E=kCtknZ2_! z%RKJ&g{BIKsJZQ^mC7Q7gw#qcQ1zd-h>8lSkH09is;Wvr|ExqMpp>G%{wbnrf8ROh zn{#&d?(D2{9julpcfC6^-+6rJd!6rb=9Q^We%2qJ=Y7a*X>p-2wP6v&vv)M zX4-Xvr2nb@@sIak?$2j4k-Zj&Y1DN3*)}}UbUnWnIYIxWezuPuPdq=aEBIZp(@eZD z$idwyciP?cQh(l^$)*x7@g3t_=p*Qx))-B`zj$>->2{9!+ z>YfBxO$}itn*pZnc4YTlW6iETvwhpPtF99}7L7kj#d^mURxw<&*2C0FLMuuG>jGoI zdQxJ*dVw%tEr*fihfUkJS{h$<3r$*fuV+czSj(R8pwY;&nqkj#T2>gKT{ItA@p_y% z-IEp;)k*;MG*)tjV12JC2+6VoJday=)`?cVCR&`B+4l2)v+8 z&D*#}7)@wSs*Ac>!k=Lk3$=w<)m-p+buKsy#-1v0!FzJP`{dJJ6eohh*F4|10!NP5 zwO1WMhs`jGApNXWP!2?3Y=z5AQu7a;s-LF+PgrYS;__uMMlS>-ovxpLw0`OYh!KSQ z+b}CZGD8~rv<@|D?!sa z!&3C8(Y40lhbP0}OaX%>3ggbxb?Zr=a0KjFZ7;#xL3UmeM(aHH(r5G_yVVCtT5?Ve zvO{3dYBSl~QtJCo((t`ln;2TlLFdq&h6e#}=p1Q6xSAK+f=YxoAoWUYLn{BI71*m@ znZm5U zwO66~6B5i!i2;AOQoA7?=~gzQgi;u&GpnCKJoZIP%K;N-LRGVj+OSH!yT(u^8znf6iYJ?g5FUyC9f-ioyiO(j}+Vpd^xHfX`MXNd{0P zIl6~zT8fc=w!J3o*N+(lZ3-LMnJbNtq+w$2I)(`Rn-4yC5sy6h;29`pD+m)Sg@PgR zu~@4?rKeHs)N(qE7p<^I`xO!=fuM3S@aS*Jo zBJ$xOpO|2^D@k!7nxNMh!w6%$plJHt%~gvUMa|5et!QA9&2z7SEzDwqa^=aAiC5yB~s~ z6*;7&lxY$yd+iiEK9Uwa<+~=DC2{K^HOoiyS(XbWA~uG3M@1O2l^Eu94&#nS z-ph&v$SB1=Ur>P3CUxxL76l=YKOi9?uPjqLhBqW`!czrf^kdkYyu2uE)yKS`0r8%= zXW*j~+e6(X+zn{Yg9Im!lW6v=HjCamau`}lb*>dqZY=9g8Z0lM{Gpd>u>e<&c3P@C z)KYPeLLJ;a9v5YU-Inbk#Rmo2xDJ$=YV5HyxNzq6;E>d#7YIipyF%Tm&MHk@?g@6% z0vW^mXemzSvz=m$*^W4A!TpF&NT=n#Q*gy~u2VC2b`tzkCJM7@K*N~`FR8gp?!#S6 z*SpyN_B*elk!%+(Bp~BJ zDd9ID!;BntV6Ip?323`9XEbE2{_m-Qv%l5gqyxq7n5%|wXb$_sLVM#m?6Bf69*N0e zr8Co=GAK_%D^^yXrqh_DDR=t$3D%8a^tz4i$Nif7mt-c8fzMLd&}lQ-UbSCqERn5m zih!qIZ2I0yv+MzG#7>g-tan>iqtuxdJOk%Xqi4e%_ik$eCO!P|f+`kP?MV9O@xUxE z)>btqu?_b4Hc%Fq_~o%8%8bNcnNg2yrK3=rkr4Y1BL6#{dHtHE> zXGIv2=nS*H0*omc7)~#sLG|zygU-a3U=Y(arZY|UL~7#kGO`?^dqqE0=>FV0>ehMQ z`Ae&i15=wstxk$-ODO`b7DX$ikry)wY)xaDFdmtRFo<)GDZ+R-U$6-{=R6cEoU%eA zBVtxdy+xsKMeL2@X&gIK9A-J!ou*a8er=^Gf~kP85YltC(L1Y~G<5Sbg?Smed0KYN z80DWDCzlJbo=;6bg&#c-Y?~-&oa{fH}vCrvgwYFedn#V?22aJmM<>XP0 zK9T_pbFKo6DFYbJAjNMC?s$#(!E4&%cNO*?S$UG`D8g@b?R7+std_SdLPQC+W@?{- zNR!luDu68m#=^3wTOUGPp@~h|vWJ}?Q8fnyMWdV0b1%***YMJHex$IDtpQ`pIC|8N~^`Tm~9fGM3|uM=`be7 zQ#ZqWvI3=&RwU0A!x&Ur@XM5#8Xn~-5Mhy{pa;__L`DIe)je^MO z&|f)Q5HUQU*n&q|WdqAFe_D|kNYpXRS1Z7nqK@GVA{r^`u5E`=tEJtQ5b_Oq2~s?X z$Z4GWq7+$?_)F{+q~jpML8d6^3}jHZo&yn4#GJzDk%KTg!V<@Xuvk=ECo5`oDPj^v zEx5M4>q&||3Tbs2qlME80a;LD>f4bJv!Wj&;1H&caM16!o619u<+xX$d<7i z5jFa;&*^EsxCPVFY&B}b!l*c#lSeuFNQ*PfyDGq#TAbkwQXHwpvs-$@^2>#_sj5j| zEx?uInl$NxB3173*4VJ{Xg1*lV|$`#-ngQv`!f?^f|zy~6XU6yVLn!YQdv1Mj6tQ< z1?EBCJtzZEg;6LGWcZH8##bi728AI`E4uh{#hDS`GRz-UfHC=&;WS1%--3;u@6msi z4J%SZ8wq1&Z+i7 zZz5SzrWe%IJ?b=vV}*Jv4M{FDLKJ@oyiXYa=zJH5?tBj)AkU5w@^~2S>GjZ@kiE?e zdBEDJ39QwGwV~aNThp zS}w;8t-)hz4R}md)_`H|R=tf2ThSUYOrVQ|EM`Ef-j zdL8uoWrtQ_s0c5UX{cy3iEI^mWXP5oGLV!3!UmGj$E>Kn5;69^Zh7!(Ap>`Z9CMZ0 z*dtG)ylA+(l)@xwkNL0sA&uQXnFzaNcfD6(_m6Xq(lN(t7htwhh;X2IQ24)Na>{e@ zny72Dyk%KvD9V(=SquNwtY?K&o`Q=G3K5x}6-yv#$qQ3*=F6>wESjNeIT!>~N9zSm zKW%~Rk!wmx&ql3)YG2r?6f{C8$w6uk*eGqIptVgo5va(bL^#~bc@T9{DwM#T3%)$B zMu0S>6=W|F2;fonMGY(9o-A@S@>lD#S3@MdV7y*@Qcm8ivJ`iW%sict_vj5G)sW?1 zE37m&sM}}D@4t8xm!rJr5hD|6mq;1K*k7s1Eyqu7DPQjd>JyTJ=Go#(YROa7PUPSq ziFj_9XJ@kgPJmMos8qW(s#LL%06wodJ-hx?5F_v<#3aYb3M?lp+hy&ckr|M{rZW&$kw&HDt1NQO6EEDP5f}^mpGBV06#;J^F-{i1Bk${V{7Iqp@fOf|wT?V4!3n!_ z%;={10ru97ClPM?-*T}&=x{b@>#WzdgKGxzV;=A)+oK5IO=iyZC+Wb)SwDR*F0pF zMpP@OQpf55oUPtUI|`8@(L`FfJl-U}!FGgFwnfDr6=2tJ7Dji%q39-%vgE^?*mfpt zA#%E?@vC9KP8pD^9vxQTL^sw5InrtrL>xef@B)bgPsn(vv`*w9PAM_ciN#26pa~=Q z;D(!!sSBVQc?`)7k7X4HoS;S(Hkq1_l6^m;UX*eR2KX8E$`bfoQ0dH>TabEl{q)cl z>ZgmN^iu@?B<XET78tQa{$$cBc(LgqlP2OL_cjOH}r5r)SCWUaHHME?SpOE=LT zDu2Y$5P61B_UH}vZJ0*yE$BQ~n?|Q69w8e|Hvp-%@H2%GjW?%$QE6eG%YZpmFPZFk zbBdeR3cehM+_G$f{U|rVN?hZ=c3y5cg#oU1n)zllH^^ajU!WtZa7I_*geswXeB=Nd zDd_S59^T3>;)`f~oJp?f>hjhP%2E?E#5&VUT){gcGA67*7 zJ2`@jLC(=4;@TxR<5XEmUUoLR@M`lrIKIv(>zdVjs&1H~9^1CaE9NBYp@($s;z_Ij$t0ILAn_;AWbXyh9Us$Azq< z0}TtpQaJaJ6wH!N>$+bUEVn8tY^#7@7F%1}sHVR^n~44>BKeY{zprZgE4U5$4hs$U z@U?BAyZ`ruqOo4YP`M#MT+dklN{;n%^+d)4!+f~{j2X0II4xny$47m!RMH}RG)%Ue z+>Ej|e;NlvE_o>DpGH|PGUxm5G>+#Tf{L4Ud6}l4UuRqtM55Bbxwic&jzDAez(iOjrd%4r>VV5Gqf>9q0`JY`eO@A+ z`%EW>las)<^6i+zRwb9U(4MB3!I@RB!Y1;_CpIZqKCk)~&Z|8zFL!kE@n64q>`5EP zJcq$cv&93_3M<<}>YT3kNdp|>8yk^K@Rv4fD40)WmI!7>;kwf@k3CZt$=I>Ty_nlZ z0|g6o*GSudDMfW}sKmVVymju9b@9?w>xCySUbU`XqMujafBwobA#vy&k6Aq_V}tTU zf%c1$z)kM&FQBBXHEkTdX%ob;G~D!_=Fbll##pWZ$y8ZU{K=yi`?JsG#WuI%GU@5^ zpxKJj%5GFhkEeT9A!^*#iwZLtMl-sh7=CnKhU59jU$}?!vnxapVfYB@d3fdP*mNyZ zi91qQNCANKjq|`%{QkIL57H+HamS(MAff>fp+%rjSc|AG%k>DII%qg8Ncj#$6G^F| zdQN#S@mafHZ5BsqQ$0OSeYK*E7wyMp3GI#ZvYEhrE+_N zs!6AcxmUcdhX8`Veo|0yo&c*1GQ}p+4C8(Dcs>|9enRuW^EahOV|{Hlq9~7hEu%bsrn=ZF;m85ftMX`0dw;%#w6{8n_TKYe`N9E; zOvr-fJRCu1#=?{d9IDT-qjfS@0>pOVWD9$gM*`bPI!ItpyzX|iBuUJ6DIDf^0v6DPu012K{V$+%zP=ouup^c^5knzUS7|h_g zc6#Spyk5u_#G5(9Yb*Y zjMKu;l=6qRXZvtCFujeWk-vLn4`0Fl7w;g+c4OzAKyBmYDhFZn$+x8}DPBI3pE0=qVm8xu5RkWVK0DxNVDXZ<(e2^Koa_cUNx=$!&Z?hjrw=-b6Mpj&^%3+vf$nG-==nf{+e<#Bpe8vRwPQTI}IF zO4ZGq4JV4isDZTMmXFF}an!MgGsUv~VVal^0#Blqes;8Qr_e;_&@P;&xKFmL$H34> z25%IAvja2-P+05&MZP$|Z7-ki28_3GpxbSDr%v`Jd3pjJ`YFzIrXVHoFfDCI!id)b zg|driANFNoLtn~n^FUO4TWPmP2i{4-17gJmaauGS|J2}qaYc|cEx*3hi=DI;HgM1! zo;rYoA`wJrn2>@>nn{BaM zb9e#IVfuznDC-oG5-UutwXo!Kc==HN6C`?&xC)dLv_XhIY=NZz?12ZeeLbhw08-=| z9cVH*8MFs_$JmKEvbS(bJ}$>~=^?L&QG21E-9b-^0pQ67(p<4TI075z>p8vJeW%_5 zeC~^un}z1-if;aXZl1QMM6&R9)ZzPI7JY#27u=-lqq7;jga%yHO5Fa1-Puv_Tep$3 zXFh?3JmPO7I}oqqWTNX0*K4~z{y@Jw5flfx?}@uONkg7(9s^Nt62HY!=in@Qy$We3&!qCl+vvJ`6@ z*$z5+7Vj*|c1v*r{sk%0?w;PS(vU}#irF2+pg>xQa87{C@UA9$$VNdn39|v)c#eE?;o9DV{o)(A}m(wQ(b*1zBcraRM#9 zP3vVGXG<65_xa8bV3c&eM;~8;!@Bba^l=n%kIviZ<6r3G2lR0YiF}1(NBa1E0{bF;`~<$*&VSLzcc{^Sz(<~ynxc(`S!>j$vkeN8?2htZW zR*R_!fMn6_xw;v+JeOYTe9SbY``|n5U?a`?!9^<3-b`Njb&Mqkz_1T#HjB~-#dLZGd)cA z=<3?51PCPDFpy2Sd|C5KV6zai2_&#UFl1p#AdfE)Hi3{25)!=M=0ON#H(5dmko`|p zovP}`%yeImjcl$zXx-`V>Z)_U+;>rUH4n(#@t%171X?N zp|`RYRJ%>D6)n7RVe=~&&M$20t?Ib5VbJYVy@lRIc%xeP8?}ztS~#`PTSu=)ej^-H zAbky~>k*Ev?LdrjAITQ%p!LDik? zHr$Sn7ExIgz3jMmj@p!?#A_C0yO+0Jv@%+#Z|JS6XtL^;_LeJZ4)-o=_$_bYaCg$} zt#+fR<4<-Y)Jard>eoV|a7DG@h9Pd^?`18wDgRno>$c60Nw<2Y<4w^!-QJ4Gou)?% z^(*Q(9=y1IL+{}Dy`k3$$9=aIR)Z)Szs)=AHG(#=dHhT(m~D8qX|G%jn$4gUmS=;` znQ$Bp4##Cf$D4{tW6jz^{VDa!>(|#W?M{L#t3aYV-ErG>i>W6j(Ywd%o>TLt+-@Us zxVRHa9!~`w=RoVM*Ybm-w;ggiUNz{{LdOrO1Q=3t{FW2p1E+oYR=HDamep&goi?a- zr#;bC%vO{+S@$~LsZI4LYKMEr$5m0393xW3s$QoxR;`bNPk66Y^)yxEo5!33k>fVP z02NmoT?nG%I<0PV((5?EloPZ`qTGfdWXks%Xz^^_uhyNqd)9L%J+I|>Eq4;Uq~;&o ze;=`Nt22@oatkWVO0-!>=BE0_-t8md^@0*x^zS(JZ~cbD^&26X=;aj+Kk_n8#OXjrBD-KOF)k{NEc{9)R8C|^5!%kk-M$6x5}ScL2eG7n~wIsF)kWnZq{EdjW` ztT&KPZazNMPxfwK1cTC|KY(QykM$$Q8z^UGs{wsr3@a6)T2B1>t+2AFS zU@Pmp14|YMk7_rJf@TUjqCg;=Ld0(9x2CPn-V{2jocKOUSL<%e51V5SlpQUAWdUF{ zoCZu)WB@Y?+T{j;yK`EWugLbDcI0;eW`wH}N_CsWN9V*h+mL1d96mVfM|CHf4V;=k zB>*#WguMaydf{G;J@0>P`SS299(=@{u_WYvTXO4rxWjvEW6WcGNZd6*@hbZ>!vSrX z0yI&(0JI~c?jF;&7>UD`fZN7Ou&TEPo>0S!Dh)q0KAG)Qt)eFtScs;DtkUPIYaQyn z=Jc6r=k(r~Scecs7ls$I+zlaf&l&HaNJZJYxZzaHhwjK|B?H&Qpx3CD6VYmy>wA>nTuvi%tU=!NI%Mb(OcP6T+uY@ z8-~Vz%1 zHOxOA%&zAfy{m3N=Qi67&$;W^k;BTgGjB7WX*SPX5631yr)fC3T1wN*lT=9nox%8z z+(&Re6*L;btQgL@7!s+*!Siq(j4;vA$kUz&dm@`e+k?p&4Bj_uV^HmQaBfge4W`uF zLeHGD7@h~+P+Cs7T+%u7I}X$_^f3&>8;vfFpK?pHHW2GiyWbrtr z!1U^tLcL0^@8yGf^;3rfbb_$dEf{Dxs^G0#jk*{RD@SrR=r(B7E5^>kFO`la993zn zWtXumV4&ab1ZVx4wE2Fc0Z8ajSChHNpIv+%y{5cX9`kZ-s;iwa=tT66>Sygs;J06c z7aA5{{K_PT6lW|~;>71}xagt>Ry+8w6myG9 zdmVXOK0^3zZxxrL+8*MC5)b&M{ixoZ90LH1H|NUeebV&OR`FR=9`_MUYBnKbce}0W zE}}g6$jQ<@b5T8Lm9{#iyWF$xF{pAoDxFG}u9>LTvB-_OAvFMk>Yw%Onr0A6L@;Ns z`Zq>~Xo?6DQrSau&Rz0l=Qsrpt*?j|{V?oO154YJPtFDn1TpE+p5&u8h!QQ^wtYu= z=dRt!=lE!g3Qp{J)}HdNTXyX#X(pYwDE6D}j^B#*s((?!bViDb7X-nXY!Y;9cJ4~G z)DI_ROUe_w%iDKt+qLIep5m#l=@5c${xob0^|I&O+d>C-;DXI1+on764jL-cHxcd?O<`!cv)jb5IzpV+ z*)OA?4u$P#F#f_$&}}Eb=vLuq&oznOL$@DKKJ9iI^n_);IR}AkMPor{I-4&Td+c@n zN;i~pp6EdF#H-d!LU*TB) z#!Ny^DhL&WANb@+EqGLAymg`x^3957GxS9jjq&71CcLUiw`-)42CeCUT&zfIA3;_dCVF2XE` z0ViMcY7idW#yi_vwd7O36@oXIo(Nj#EriM=intH_U=v?-Q@k$;U5B-7yKS#y`Y*{T zrC=3E9K`y5*<`dWE#}FlVw55^(1e%5py|=*g*!^zar z!*+MF;aAy9OID#kKh`rDhJgA|en>RGl2R(!n^|2SwlRGX02Ze!7VC-MhmPHwY);sn zZ2A%6+7(Ru_(E}K+?I#Q0`K{Q>Qjn>$Zb^2Gk3DZi{L*(e;>u%$yDp3ySs8*P6U7<~~7!U-V zG?noh1cgwP5PBDMNE=d(pjYU>5_jNjfw$GU3%!`&gM1AyDq2eNyKbZ3d(*H+tqOm3 z&=;rNrr(&;uc8J0z6npc75Q*vGf3wK(!Xgo*iTC$*en1o=v2`Q20885`0tXbmHKM} z|CRCoZRPDdcJ3nbtKPr;!bLDQcp0AErYw654klqfc3KAArsY%>#nT4>?)vYQXU( z_Ve2wemaH$#A)-(W`_Xn5EE)7Eo#JWHK$~QIyrpw+V+WUd&c3IL9%YK-$fH?fRKwR zk|=VzXx6tjhUx1@4d$9G#Q2mOM&q~a+OvJfF6;X&E+thDHRVo3u@S_}e2b>7MSJhq zckFl>lPrD}01%Vr1S`{;sF**fo!ch%?B2N}IU=CO+6_HQ4!03QL(5~-%3F5t-g8UR zJ5M(9fIzHh&e?QNI9II)4QRpUMYmdW+LpI!(2@%#9vy>lS5R*`12B1!_5feaV1r=a z@p=Vw4B>oaVPYEIq+`6LPxQV{&HQ&}q6g#OBVzpQVK;)<};yX*$7H zBRKC(Hv?%)ZX4qtIqVs4*QQM8+NH@_P?#nIsky%r2E;CHJdBL;F;)vnFs~C}^DtXQ z6-8``nUTeG*7EaD(t3%2U=W>uBH}s->c0Kg(&*Ko}zF%i$O1Kg2DXxxlCx zk#49_C&2g}qSTmkFoMCm_<#&ztJhT(c$>!6G@PaYhX*GeL$r3cgE6;f$87|8xSWsk zUeJS>#Ti>Y#Fz$@GZ zKz>*+osWOi{IXSEEK&j?)U$CdEKNaAFx8Xpb82GzU2b$~+Cy(gaMhDv<2UGE?zhrC z0pe7H7+4Lk`qXbhKSe9bJGPJAvUB&I?OUDl?uoJ8J8s#r{ZwY>XK0_OSqG}|#YnEu zA}o=&(;OFN67n1`X+P{!evpl#3i!VV(5)OxAc-T}w9B2WLjKUp#zfBgXMC~}r9MQ` z_ws%V{YBxBuwsWj1Haw){#z8Rw^o-eQ+0g!PyV&W+vgVbyye2D$?z zTr}5oZOZ%M%IM!X>-ov4K2j%_NDDdIwryhjjy{br=n?BG{yP1uVC8PN+me9|m|HTW zfCkU)U=~+R4U)}mdI)YK_JLaz+9WB+{BD|-_#N|0(Wkl@bA}>hYWFQ-nzTrrNR@F6 zi_{Y0O9DG6@Co0c3j1z9_L^|~rh}BM@Z4nP1Wy+MKM|BhbmW%IkpyaU5#gjJ-9v$Q z3cY||Vx?Q?s7h^9uG!cdQj#Ae z+CwrROaq!dk9$(!PzozR%6}X|K@sX-a|c9kqR$vfQbh8UvcR z{+Qg#;M6^r7Obd*f*X732c}VH3peV!s!?ICMqNhx7&u3S{9!8pslt_iUse8UQ@KeB zasD`#aZr7QPQiGC3z! zE19-BRv|6nbxn$p@y%kTFAD+iP=q8z7A)@^vTI;RyI3ZSecUxH?U4)jqB)();sS1= z>6XtH>J}2R%hKIq3E67HL`&4-cjE$Q`q@aF^}+S31Iikpjltq)2E0?&ih(zuHCTJZ z+L^5dI&s%9@0*2~M>4&fnfG-g(*vy2rALn(W%Ln$o4PN$q+o8KLo2!N@0q%d9r#hw zr=#rh*?hp=X-TVLm4A8jfyE zd}%n8uV#*NBlOtbO zT7->CS)aYucoAidv6QFTRA9YgU|7BquZmr{Jg(->!&WAQ1C+*!tbo{6Oj|?tQ`*7< zCa3WoB0(^V#NrAY$vIF+atH_3vgF*Mib8S*;J^k%xkMW5F*Zls^o%E_T`w)%t}D1* z_nCGXjQBh;S?;1?%j$vE!5n3ZeDu7?e%|9&m9R|N`^6b~-ZhC`8J0OeqF4vkYwQy5%hm)lm#lNQXfkr;!h@5K6pKskKjw{X#a;l~mM4&k@}PfYR9*D& zE8Z$Q>ETzr?J?;lOEq7cP%TR}GoV=MXvPzx4F56l#o@|&6)P(@Mks6hv6h^CTv;yV zi|rNvH1xl7MD(AsBp4DxG7R|`nG~A_GuQK@m+mkNz23qJLOEk-|8%(PghJ}P7R<^k z6_xw|)LLEgi9&3pf!)!uB-M;FRP&w5D@wjQ-96O*UOxtht*kK)vPqcAlanVP>ZK#eX` zgc{n|ikLT7E$eJ#ci<--2--sN4x?k3Fzlhs$Dy}a~ z#dS=@lL}Cw3+19h={~1sWOdQHuO7rH*-@C1Cov@x1t`&la#3=H><_(Wk4d?TyM&*_ zX}PN~El*}zURZz@T__hVO19*#YbHd?mbe|K!Yxe2Q<#dE6`(>F%0!VwSsJW_@ZuZoscr+I=AaQeVHf*rkvs;+O!?C-@@uxLla0deG%|cdVQg^0 zV*upNhA&>D9l0(gZ6?oNhq~i!l3%8K!8vpzOFXwrIP3rShp_LB2hFU=??G!WX6o>dK!=Yh;nc^HWKZ^padqe;v!mNV zzL(4qwwc19Ah#H2L;Yyfd)lv^&M~$oZ56L8#XyA$e-mVO`_ugs$COpvSE0`5P>xR+Cq#e&u%S-=^`O8Bya`vgqV%84s@&L;0s^ z*I$mPT}RakR9b}LE*P1Gn^0Vg2T_<4!~aii>TC?}r!X4Bv*pS@%xoqpE&Ux75>^@l z>5pbXT5sj;@?Z{mloxcv+%TQF`m&%5*u{;ej8eV3=KoE}RYe$+TDH3Lg)u7hF} zTUj@A0)jvD5?r94)?&ItPrn%7GumSGx~HSMWn~WRNlyLH%-AK@CLGd}ZTThvZ_<+m zoM&4fk&5JsCfO=mrQGiuK-p0UP-r4^Cj-iaDhiXU2UopcH&bfl58ktVaqMUwlBe8%c*!$U;4O12fSgr@Ia!5;a<~j?m}*y@S1LYBuvdm@fwTu zOk?bxq3Yy_sEXNark6cDqua@#0^4lOs!VDBiF+YO7^h>lP#ji_K{t;5!zcsGB9UMm z**L`+iah3k7k}jF{sXtEm1C4XKEJH%0R)S&NEvSl@PUyv#_G&4(G8;)-v<&k3>V)$ zEWX@0A->lt@lEn6A2G`WH(4gtFC&ewA5kM?(#XxvFO8aVOB(4wP&y&1^71a$YFOt) zr4CvAgOg7qj61cOf>1UxV@Vf*HFBahT`c;dgrz{^XqHaUPM-Cq#)}R*UWfciq6NW-!x36J^*a?LQ3;J|=p+#9lBiR+KxTzGZ;eitxHXZ;lW*;-6nqoh zk`jxN!RH~cBN}Numqr>!ijAK3v?pI?&%exLfpX0AH;XKFkufgPXRweOm1vJX->76K zuLRsL4^o#aE1gYes+5B}9LH%?o~~LQcfOe|>*5LT?$JF(GZV26&`1)X!#wo{#jxnL!up>cG&6}>|Kj?5sd zcW*pepEq3GQizLW>+WSPW-=s~f!$NM()-et#tdxlXQj~+=kl?t#EomeqY_K$V-iKD zievP|ff*_rf0wcdCpuE(f5hD|n2M0=nNQQOjM;_QGTHqA`a94OBQhK($Z!~uFpAY9 zq$;~Ul4xM?X)VEzBUs7=XjsYzlB)%j;!DE;u*#%xBk};CE|f|CSJD7TCtx6_JrGTF z2gTKJcnl5kh^SPbBKWm*L$#%^VGw4pxF0Y^PC zoMtqD=0M>9%TqLPFfLBb!1xh|Ze(pd)j<42C(}sP>k3H~83d1|DpNpm8H5K5S2~@p zG;R;(i`CyH2}XG zgpUY->jc223oHO8AcU`uLt`!Uwa_sIy&CfJLGP6Wz3S)~bpS7eSJopVYo9FC?F7ax z?)HzXqA@UDr@&ak@F3UpbBUTQ6kaY%GX?z9wEE8yWryQ#n_JD*=D}TED3er#hcrMc z$CLa=M6B%nhDcn$X}>(PdNWXujz&%e!DKNk9y=2%$=~YuILD|pCuh&4OX`I6pbIBg z#FP{C)wmuO^G1Bq%LefF_*L&{IKPY#STF>5uDy4OKV(QxqM`}*d<&vthI2FzzLy?W)r6l zm8EuA0GS0{DWueRln*I42&AmLZCIg-*a5{blkvpJ)YHKY$|Ay1`N4=oIQal~ucL}C z5+}DMYA%A4wC)zp8m#iC4Xfoqm|jr=4>V z1q{SeZnMh{$0X@biI2c>p~-@yh|CZ@GQMyK$Fy}?4i>hQ)SA2c#uKYAaBg7zmgWbR zZ#@Ez;7fyeLLVQqLRE(f$tt1tkF%_1iJi4jYQQ|h$-Ovh!`21S#$XBYOi^S)jOVnHhpWmD)I~<>Xnp@4)=D}xOD2vn+Q<;c_ zRSAJOBoYoR4a{lBv+5F!gK=0UUlnkS{~_QiRya&G+-WPOD#~#gyn`S?7~r`)T@&Mf zxt^I$Y!fKj#_x)5U0hKWdt$&s&0;25TpXO&Xz5fl|d_7IHOZeI*ayD_5dcN zNysddLSR!fH%Z+U!HW)#scibK5L4L^krcGh2mTKXq`kLWq+WoX!tipTH`5^9 zhZ4LVj2RCB>3WPA+)Y5bjrHZ`lYF0@TVn$HP08p_W+6&G)BBl1bdbG&1JhwDjho(c zw&|6a#b$(zuaHEVjTAV5fjH@GghRNYv^Yx;ktl4Tg7@Z5(u|S7CA9)k95yV^FeDHN zaj+={>PYn7q2qq_Ieon!Tm!UY@MW-dM2^AFkYiwYZKR?{##qca1E0%msEuooX{%Gt zfi}SToP+h!Ip|^;c15`3th(t3MzX(ENXW=7coPfRKdGXNbPFz95g#xXaSJX_lpU<% zG;I5MZZ%h%$1Tu>GD-bU7I0hPEjbc`mQc`&mNQcDKC!4P9nWGjiu5a#C9kGdm67!% zyG;5fmV?P7o_%3bp`TGl&dtIH(eoENXm#N>(8!-ts3!^J9^{_P?37%gsIkJ8z9n60 z99eIPA*<0rf>rE|Fq7y&M{C$?LE|I%g2uL6LD-0}?X84uhQ$`P5u5<=j)hZL4$JJ#`=1kq+(K>UdFg41ti5p&alr z#Pp|_2lYb?gk*xcP($0}sKrJ?Us6BM%Q@5}pp=pbSTM?m$5rlF5AnYARHY)36_(m%-{? zcGwGsbp_be)!B=eIu*4-r4qT*oQ+n&E#fgJCYE@f<+BguxfT9-IH5O|&SmU>RN?rH zCk8*hmiXduP5c0BA~%MD9KB^i4DvPgnoMC~udL5g)8y}tsL3m(ra(H)x0$B=0UFJY zER5-SmPdr3oK{?T@0g5LNpppAo+e+#5BGLkmSu{fPqb@BrfP%FF3Y3CX zC3`mN)!UrAI*aD3SN0u1Z%8$Ydnx0I;o|j)FAf)~53*2kW3q*cpK|wD^8aKKs%$=S zn+LsO8b3Co#%GCFvi-)l=okOfjL8(QXUF@SYy%?i7|kQ*CIjTdm-{`UZy2`SQHX8i zlzy1|Jd?CsPU-Q&m3|~$Y1}E@Z9Apf{F7sPH^wlSWNu=0CrzN-jeQoF+UO!}pEdek zY;nm*IG&RrX+)0fL*&RB<{Dw^kv~~B&W*JaBU#K(5mHh;F=KZSZB3;?nC2F={g_p#srt?qJ>Nh6J4#&Dra;v%8Jg%%Rlu7C# z3kP_bOL>27?CIC@h^iy9T|d1Pj{9lEUo|{?cOjk;R{Re0ER+0PSnJRprMvzD5XZA?*9NT9VZ z9}-+gNT9N3BBz8ow1UO0{|iQPzEY?Y2_rtko%m%{bdebG^+e4@FyfyRWrt(LA91U> z+B_Jc3uTh}r)i9!p-79CSgBbCyH_#?ysG7S%4jicrv3pKOw zfFM+RS^HEhSZ$jzxvPA)7241`;;(A_{Sh!=MELu8!e7%B7XA|SVb_8O2Xne?YoXubU@L`@8jJE_q*!Uw?oKu^ z_7`C|90tSMkon9=+AkLBbi&EM;ZA>>DjLJdtK&ProK5#0y;~-D$WBf0-bDRH(DFlx zvcu8x@3`$;E!vKR396NbEBu&4d8Tjsg~Ifgv$%5NCY;icjjCV|JGfQ{X8O0uxe&P| zbqnHZTLk`EpNhZg_)+LJrpPf?zO-2W=8Je7R=&~tRtoZ~^MJ)rI|I;Z*{oPD=Q=Z3 z7}3InIU#Yi;h_YU1&eKIvN`ntJJjeC)Fztjp}z%vVIAn6D4tptgaCBx3#!#NgSLp- zrCGe@5%qHMu#=?Q%6g7QAjS>bg*Jl?W6rUFTHW-g>yfEVY|OJ8%}qsc%~(1`wlHy; zDx7d6=}dhCsXES3rU~-_wVFQp0d2)dSMGb11jY)ke>R~&^;Nxfp?u(%Uy4`g>MGZh%n3pVkti`a9X1kDU|`;L*$%L4#h`Jb*J_ z8y#n=MnG-Z)S@>Eh00CxYNL596ZS158s8lq13vS_QgOp0R)GA5M(a+Nq3OxZ7jomY zJT;E8?NMHNzeZrJo#f#!nnqr|y6D*cA6UUN8=1=+Efucxo9Rm9-ss)7HyZbr$RFiH z9O!6sWeSl=w>fT^opF`F+L}`t?MEfk;a5(8{1N%7|44qS=?LS?$OYUMd1dk&O@uYm zbxirH+8@m4tBQF}Iw~a$=n#^MH7m++GUyc}l?Mw62zjpGVgb2R6^(hW`EwS$BvEq_ zpVdv29cVA>G{XNjx0djD%m+YjEJw-r<;Y1m`>IB?Po2 z2ksWRe%+R_Q+oNfJjMnN5w_>bV5+PFXGUTvkdzM8gW|L;9BYvfV#9Abd$NUE^nwGK z89^>8qFoxC6+uQBltX5{4?~KwSaRgjTr`Js@g8}^SWbjv6Nj$vbT+{P(q0gx?nMlw z6Ep=s?8sOazr-11W(V+6AN&COz@SLCkUmnRP4*9Abw!>@R77$uh1`V)zsv`{%?JrFNHOL4;b;_DJ$9FEoBW!d1yh=I)t zxt7ab%Eiy~`+fS;nPQjArTWi>=pkAEKGS0=jk{FOwOp!fqfVaHy?WUg1t5+GNQ52* zc6{%Venz`ZzX1|Q}yTdHSyPlLReloO?0lYCB;@XWAcR_-aT zU`Mnc5BMdY8NmC)LP9`p)3QtIH`KR+8NaWJ#@wbGlL0@`80?#_A#xuM3jKX4(Gp8x zc_mBVg)I*!$_`h}6-)(JD^znmHhU2BOnVKd_{ID>s_V$)R5LrE6RV#Cbh`ieMm!cG zB4#2>x;4CueMk@V9^+aK`@U1CiwJF2aTjH>FBinETvK$Yx+Yy|9OCRnbGlok$`Q8B z1ohS!@)$nf8Zz3@w%Fnt(l&ym5kcDJm&CN#f;0jYI=DsxN?C}Kg=Lv|lL9df6!}1G zBdxj7b?ReRcof+0v5~NCg*uy{>`LzJF;z4MW%);d&r8%?1iD_BC_5awuI5&AwRuK> zx=<#m-_OP(`K50GCNGQyUI3vR3mMBm{TabA)d_)%HNn}9`HI@Y-xV9_^YpG>K z`T=^%j%bw5XGesiZTaBVCKQ(7L9ZBr{iQ-3O!nld+`;cqMHgvL-k+%1QrMxc@I#5R z!`19*+-j~ik3G?aGD-d4**I$Tir8Mwn}Z0udurqX8iqV>aG)L6d7)g3l&|!xF4T21Wif@x|fd_H-6EZj3P@9_8?f^MagdBSFu~Fn3&qF|?6b~A zwPv3dS6Ewy?}D5WS%znlWiT{amO+F|EXuG+opHdj4uc>%Wg#@~=Ccr2&`5(;VN~Ed z`d-LpA$8wK*R_`y8Ay^X*vcJ!wJI931so<($F0a2+FXaXJR{K(ONBRPe~roO_t;Qb zPJDZ~GLJEp+^jsdLl??q%^R}8)LL&UdksSX#JTk&|)wvf-# zPQaafAdXCvy&_kB6A&K9SaHADos6l&`$V#Ij8yM(G5fd=XHI!7>)f@HDlEI7O21eN z!ZvvXnteLVh0z#|%%{Na5h3$VLT1zP7BUn5m5K9Z$tVksQ_z^gV2yYAFu2doc@^R9 z^VG=vxkBPcc>Ej|zpg48!{fro#r$NV0Tv7=4u(-ACGHwh-jMjxaL|1olfsS21G>6U z7X2r-WG(?PC&tkDO&{n&=`!>(&Um0^%(=JK@Xt`9#Owqd%Fo7QEC~=FqP(tHP?&!+ zIFhe=O=O9c2Ol8fZO)yMc9cAKm_A?gnmpzA#51Aw_Cdb`Gvm+# z9(zz7cH6O>ASuC9DL=Lf?MCdDbc)XnZsM#$kybU4_9w2USh=92Smgm4bFjzGpQaSx zwA%-P-OMaM*n>%aJs$!<%PX2)Y)cXu{5_lnfTK{5zd!Wc4(_UqYeM_y`h>NG4^0ap zG7b^`VnPP+R_qYrjOUjf2QMtaOue#)`>fZ;6y`OQf0Jn3aFyTBD$k7)D*p_r@o|)bxX$fe0=n3VXCwZq9%VcW3>eWU9@}#|(DB$-YM6Jr5c5d;j-;74(BJ93>*Uk!lLv^LS{-Mti@9fU zj)XW@LLCZh4FzyKrq}X=a>r|8L1)=*`(^kaXMM2{xpNwv?40$HUShV6nQk{ZdyT%+ zi=M?=oh@Rq4(!hsoJNGg5uXo1dSQkat4(_?WAgF@qmuqc#`AI^Y6sP29FrRd^JL*o zFOMz~|0!2x*!xBjUYQ_pxX)+Vya@Y^P5>+PfN8jrl7bsym;$ubnyiOM2IE(H_bVpcz%jV>A$^*xaID2+aY@_4M zk%9wJY#H+yw6gLK5{0xGuh!3F2ynE>eI8ZM4ZW4PFz<)K zg8o~AQArD$@qE!1H1)0g7PPS8T(hp|pzx(E0Nl(+Y&iKttig*goHrC9gAHdkCBqD7 zvbDyR^$W7;dcLiMD5v4n<&3JC%6eo6lZI2FPCwIGz&@pnr#3pqcv_9wex@q+zm=<) zK?|DFXoqFKi+sNx5RP}EfqEt9@ez30f%a#R&Mo7C-bDn8D|E5aebzJOE{kMLfT zJCH1c4q1g{uHmSdjAU-Aujd=RYwz6e-0e-f)j4OsXti^P?=@4t31Rl%LKrPNCF&#lOBJr^vaoTJxlpl2V zA31tESu%Ih4Lz~*krS%x$q|ZhVSph%MwPX^Sy93aF_MwUA5Ad9@)cGxDcb4PHw+VN ziSon!g$gr~s}>OS`U{I)hCps5<0Im_E^!sQ-{9?axr2>b_3LojaMm66MsOqu*bjXpkj&Hw^qJ zvth_vhV(ZjY8o!1RVJMqnPYUA8D(D347@IZ_(7^O>Kg^)WvN7#MGJ zylHgquL_AjnVXQs|1VV0m~)kXbJjN!HCuLNX!PS-iL%2jMVDL6)#kAjx=<#mA0K8Z zkZQuh?Z?_;#A_d5H6HhL7-?R8MUjCvS&&(li_9+0WkIehTgUA6ziq$9 z&^z=!BbAq~FERup)O|Ax$VIB?B2jlkqUIu~`=mtK;i&soZZ%h%2X%F!Oj18L40S1C zO8;er7cTlf@dz{WUM?g#gu-uU$;lLgTqykP!j=AFy3#lbbH6FR^ zN@%P-fQF9SynQ;Jr~x#wQ!}smaa68wG+uWLlznk?na$% z>}25L1vT>i3dk4{^1hdl*D%yVUWHsKHhFzLC>U6%rXj;{V1X^GQ{7kx2X}iJFTb@s|^2ha>TaxYb;39wgR|lau|MG7$L0l~e+Sq$a zzI`QJhWTfti`UrHZ#uP5-+XGJTfezZ8n3I%LspW}n_}}q~ ziM`@~FSW7%k$y&-fHp`Rk;DIcWC9Gcjgs;LxReQyw3nrFl?BWiBTxWoQ)WQJXFfB~ zZ)CxJ)A8gk5e!nS#%C)|D88i?iB>WKJ7nu1BM>SDCv9FV)xkKT63L0;%k zCfaEO+OehEi)vHb3O0&{*SGJ~W=_GZSEr_`n{DO4Flk)M4Fk>rKnW3mWNt zQ6WJhbpBfwq{FIc44pYct}FI;%A_L$_j6Vf4X{9ZZR{g#gA#WQDbtBB4IdzUjY;7~ zVWnN2pxE6M9j(7{_unjrFkH>MM$fGF+C$!g}+8g08 zT*Rzmn~B0P?wx-fA^n^`@o~ZdBZ&_bl0-5IUuQ|o6slY%VZLys-$+*)HwpWaCZR7B z!8DvKxt)d|w%pQIr_^k?u~dX3_>wjiKMz7jWGcQ%royn?G8GC_Q;{Uifig4z=`9Qx zn}AYrJWiPo4YK)6$JU{y!=1utOM~8cY;}+>}+&IGWEYJbkEDFiYxly=$cS zs;i2GN5}?Tf=Ov{9`t%ubdfgTX^EPP*nrK6vcqk_W!!46HjfR^g)&L~w_zZtgE~mT ztKvF{;&+g`H;)a_drAAQGg3Z%Fx!&jNS=R27`ibhBmdZ1D#ye)9H~{KL{y{QbNao} z^B`^rE^ICsJ$gVoFy_-xN=#8gM}+ynXWW$4Yu^R26D-MdcA&;A{yOaf~JoM z-B(=-bT>@2&|P8S0CbNn+Rp`@DJ<7`m=DWKeXu+VBDYaF>wB|09F*r(BY{yNVIU;G zf`#Gbs%Q+!3*-WLRibJO%JtrVmE2PQHVyyjMCsvRzJVLg73TqST_}s%6B~2P>WVJn z6aetbMQ8Pm&(ql_m=i>xWsvvY7u;3WF3#!R4c%$V{p&_J=45)hgVX~NCY8;(OcLgc z&G3r1^Um-taj0){MI*~^FC@!k2CiaR&JxRfv%SAsxYBFVmB!7$O-VCg!4rl8sayrQ z-`57n4_;QWFHEB%q zzHTJ&3x$M%%)s?541cVOF4heEuSC_w%)s9#N)I;!H*&+d;yh+R7s{gc#FH0c26U(W z(3pZHE;VXm@l|%NU89WuUPz|N95^h~S>l<`9IU;%$dH~YEu|}sn}eIP&4HHuER#^E zj5Z5TLE}ec7M@OK!LZRX3kp^Hm<3Ih74ON5!zuHi!PS@tt0C9ct7Vx*DxQ1Wsu{0v zqA6)QRDx~1Vy$3bjb7B*sZ9oLtE!!d6MJFVoea8B86IiFYvNQO;Y5~$DdZyWcx83M zOQ*&;z^!)3@{TA^9<5cL;to_EX=uf%IVj(^k!w|&@A~C3$G6o&hm(Yt!)o1Yx@ANx z%4dLUvap%N*z=bbWna3 zt?0ynpxMTcHL{utzI_HiSF4}hP6NNzMnSbQ=~mCsQ&hK%j)R(8=v_G#1QCga_3+@u zy|p3EOT<~(m2+6r*j&J!bu|6ou24EO6buvDP`QVk<_{=XY>n*E!lig{2Z{4gs#tCm=xm^=? zR)OhNkBC}$ZEv05YImcG*Qy4z1a_gfsvAv}_mnZ^z0kWp{;-0DvPh|oeLA&<*8!iY zsnuwqcLfw9{*`6oD+|3F5>FDJnCSqsdh6tOO&hrM_3;OZ!oBrG10*c0gGCL{w9s4I zz$T(D#(Us+4Zkn(S_{3a)LK4dqJw;(8al}SaBn#dM4tkg;D}#?gnCo{xrO@j-a0zr zs$y>SE8y>2b2oNJOut@q9$A)Z&U zOA0BeMu=e`SGf?;D=IZVbSIH>OSf_bD+HA5a-={Ep#pL;6H=pIL)zO0h=+em+* z5=2df26`>}S`A&krsK|{!{twi=myd%NKR`Sg4pn}(qQ4x`kQ*|+Fl!{zD?nr-&R#H z>~gw88T2cp9KGx6QPd9ij*sJZIM$xSqKMWQW`xHVde_jKq5*ibf&=5wJ=oUOTZ#MS zXH4t_Ki74ps)^6j9rO8T^5>zfE{W_JocHB>(UhnIYCm3&nhjL83TgeJMYX8DaByYs z2FPR+so#})Y62?aJb{Jz-uiG3;C-%A_owR({2%gr87(VW=v^K*T`1biy9D=O)K%iQ z{3%kODc0VAJrrmUmK{oc1D6F0QTj}`jVjimb&(%|{}Ko0Aw5CWZ%si47#OZ3sK88m z;yu4f!b<}gp^cXbRD#T4j=csIo7^>OE%wZN$xFjT z3aHs&T7?b6UFx@)_u;WV?BbGb6I?m{sjL1(zp697*r)Pt@5&hclpeefuV#J?)nzvJ z<9N`ePMPB3z2$^NVDR~c-U_-Y|K2onCtjVooh}s&wPt>lF8guf$ISET@^|#}uj%p- zT|P{guhQi!ba^(tvWG4^=rTc<=hLU2Lzgm6KAzb^m%pRSU(@AIdvy5@U0#NL$TKJD@^QL+j4loq zRL|T%m)FqcRdo3pUH*nH2Ql+Hb0=MXl`ik0%UX(XsMVB*l`6IggAzda!2jJ4} zt)kwh-MK=FM1RkVzMdETJTLlqUi9z0=-YYGuk)f$=S6?ci@wC0=)!r?hx4NU=0)Gl zi+-CIeKs%pYhLu#yy&NS(MR*5f96Hs%!_`R7kx4>`eR=7#k}Z;dC>>+g8%b^_w$19 zXbD(5FZew#c#U>~o%4dn^Mb$gg17U6uk(VZ^MarAf|v7xkMn|u^MZf#f_L+RZ}Wm@ z^WFN>;7kgIs9!F%;YlRwLK`OOFQE+~{Ux;F)%2IphTo#Ugf@Jg{u0{oJ^D*%1C0Ts zHrz*l32m4ll@QuM#{fxf_#XWwwBco>5<(k3PJan)aI`kOlKv9f@K5xY(1zor5<(k3 zNPh`!xSv!)Xv3H3FQE;$l1d0|cpLpCwBb%t384+YPk#w*7$cPs+VBqgOK8K@q!L0K z=x|x74RjQt)CM|RNooTPucS6m7JjJ>lqXth1EnyP+CWM4q&85BC#emTazttaZAX{d zK)Vv9HqfRJsSUIgS!x5VG?Usus|utx&zo0CC9`v&6Gs}nc%+pA(}W& z#yRjNh3zD_d5y`djS>p@0AY literal 0 HcmV?d00001 diff --git a/docs/build/.doctrees/reference.doctree b/docs/build/.doctrees/reference.doctree new file mode 100644 index 0000000000000000000000000000000000000000..b4df720f62a5aad6f5619fe940c68cd383c31cfc GIT binary patch literal 3535 zcmds4TWcIg7Pc*qq|s$0IkDGZ%jvLW;}C1cgs_BtSQg@!pja3un*>5=YPxHt3RPEi z>S9R?hUCEzLA|B-|Lkr8dEfm*`A+wA&n4QB=LiP6PMtc}?_Bgv@1H;JUaSA&o-2ja z=R=m~+T`3-aWgkrD7g03_tiV!RxhiEv2WR#Gr?xOir2uA38`|+b@f#h2gL5Ba>LpC z4aYMtjqaX{o>&(fUsVr9KlZ%ziZ5Kn{&POzkOkSq1fH9p@^ezYc=f7kELkrZczq=f zVn6K+6>D*QX5UG?sifxBNf@)Z#k{w296bCYKh|XK$mWeqG3P+UcTcmT`P$4wIX{e9 zc53;ActYIpY)V&^*b@(quZzR@@#yc4TQ`zSyUch$dct3DWl9R%=v13C#q%jY%1luh z?T*fjJ#`}(>_&~DBgk&t9u|2e?ui|7U#x|(*luDz588f9h<88IFSwTG`ID!~lUb5j z9qKxAcYcLo7C-2DOnSuOiFiOE5^o?b;!VW;kNCZX-`n`T1E0mawXa|mkMQhhW?nz` zkpecgtQ3oB{OMD{ljGL!nkuDhrseHm*!gM0F^9%`3%p{q+G)zdu{JiYq zBfQE~$fcepS#aJI@*lPD5SSiQzdiGR1MtL5Q2j)AJ7YMcM|(kuDNC2*b0Z7p?7&!lsIfRYEsBP#c^wP3|8T^>rIwY&!StX>%lI2QN>#m zW4tz=FI*m9kGs^QbtuwvDwYbAfkUe-Q)*av>LBu7L*a_ol=Mt`k+z)^8fOn?t@I@B zSY8_IQ$@vC9p8vsf~oG*UshO|ho(X=b6x@* zP$PkilenH4J%Nu1hs*&_K9T2@SdRl1yh-PzctZkFyLl+ev_l=DS`#DyXEjqKaIdD+ zc&6OXNu}cJLP1&IvoT62_o6!9jE4YZk#@D&Igq-N5ONv! z-G%n-JQZ>(6n+5jO=Sr8JFZ};vabV*+96P{)#v7zDwDBUXb&@iL7gG-O|c=$bqMkL zG?Y+5n_In(&6>a^&|@+hpYyJ8i~58M;}t$x5O|egO)1jKby@*4#hB-)-wT)^IQLL; zI|J8g$_pk{iY1eJYi;(yY)u4M)uicZmvN2j7qq&?&8C;2cmYMJbBW^csb_Y|(VMWg z9l$6+%cG?NHaRV7wBhYx(aJMSdrvDDwms~Ve^_OeTCOap@y2_9ZYMu|HbWC@&kyd3 z9qE@^*y7ssZyG}I;b3k{A$7fkivM)W-1Wz;LVR`l{&%ImDR@B#>1ZhQEzJ5 literal 0 HcmV?d00001 diff --git a/docs/build/CHANGES.html b/docs/build/CHANGES.html new file mode 100644 index 000000000..ee44b916d --- /dev/null +++ b/docs/build/CHANGES.html @@ -0,0 +1,461 @@ + + + + + + + + + Changes - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+ + +
+

Changes

+
+

0.3.3-beta6 (2024-12-18)

+
    +
  • Names

    +
      +
    • Added the infrastructure to customize the division of users’ names into parts so that it can be divided as desired when, e.g., the user’s name is being auto-filled in the name fields of the upload form. This involves

      +
        +
      • a new “name_parts_local” field to the user profile schema. This field contains the user’s name parts if they have been modified within the KCWorks system. This is sometimes necessary when the user data synced from the remote user data service does not divide the user’s name correctly.

      • +
      • a cli command to update the user’s name parts.

      • +
      • a new “names” js module that contains functions to get the user’s full name, full name in inverted order, family name, and given name from the user’s name parts.

      • +
      • updates to the CreatibutorsField component to use the new “names” js module and the customized name parts if they are present in a user’s profile.

      • +
      +
    • +
    +
  • +
  • Detail page

    +
      +
    • Added missing aria-label properties for accessibility

    • +
    +
  • +
  • Collections

    +
      +
    • Fixed wording of empty results message for collection members search

      +
        +
      • Previously, the empty results message used “community” instead of “collection”.

      • +
      +
    • +
    • Tweaks to layout of collection detail page header

    • +
    +
  • +
  • Remote user data service

    +
      +
    • Fixed bug where user profile data was not being updated because comparison with initial data was not being made correctly. This means that, among other things, ORCID ids will now be added correctly when the user chooses “add self” on the upload form.

    • +
    +
  • +
+
+
+

0.3.2-beta5 (2024-12-11)

+
    +
  • Added Bluesky sharing option to detail page

  • +
  • Fixed line wrapping of long values in record sidebar details

  • +
  • Added OpenGraph image metadata property to record detail page

    +
      +
    • This allows social media platforms to display the KCWorks logo instead of a random image they might find on the page.

    • +
    +
  • +
+
+
+

0.3.1-beta4 (2024-12-10)

+
    +
  • Added sort options for publication date to record search

    +
      +
    • This allows users to sort records by the date they were published.

    • +
    • It also allows publication-date sorting in API requests to the search API. Among other things, this allows users’ KC profiles to display records in publication date order.

    • +
    +
  • +
  • Community selection modal bug fixes

    +
      +
    • This affects the modal that appears both during record submission on the upload form and during collection management on the detail page.

    • +
    • Fixed the sort order of search results in the modal. These were being sorted by record creation date, leading to a confusing sort order. It now sorts by “best match”. This allows, e.g., “Knowledge Commons” to find the main KC collection.

    • +
    • Also fixed the handling of ‘/’ in the search query string. This allows, e.g., “ARLIS/NA” to find the ARLIS/NA collection, where previously it would produce an error.

    • +
    +
  • +
+
+
+

0.3.0-beta3 (2024-11-30)

+
    +
  • Record detail page

    +
      +
    • Added ui for collection management

      +
        +
      • A new menu appears in the detail page sidebar when a user has permission to edit a record. This +allows users to manage the record’s collections right from the detail page.

      • +
      • With this menu users can now

        +
          +
        • submit a request to have an existing published record added to a collection.

        • +
        • add a record to multiple collections

        • +
        • remove a record from some or all of its collections

        • +
        • view pending collection submissions for the record

        • +
        +
      • +
      • change which collection appears as the primary collection for the record (i.e., the collection whose logo appears in the record’s detail page sidebar)

      • +
      +
    • +
    • Refactored record management menu

    • +
    • Refactored all sidebar menus (including the record management menu) to allow accessible +keyboard navigation

    • +
    • Fixed display of event metadata

    • +
    • Added display for work doi as well as version doi

      +
        +
      • Each record has at least two DOIs: a work DOI and a version DOI. The work DOI is the DOI for the record as a whole. It always points to the most recent version of the work, even if the user creates new versions in the future. The other identifier is the version DOI, which will always point to the specific version of the work that the user is currently viewing. Previously, only the version DOI was displayed, which could be confusing if the user created a new version of the work.

      • +
      +
    • +
    +
  • +
  • Upload form

    +
      +
    • Added proper messages to collections widget for published records

      +
        +
      • since collections for published records are now managed from the detail page, the collections widget now displays messages to users pointing them to the detail page to manage collections.

      • +
      +
    • +
    • Added clearer titles to form when editing an existing record +or creating a new version

      +
        +
      • Previously, the form would display “Editing Published Record” both when editing the metadata of an existing published version and when creating a new version. The header now displays “Creating New Version” when creating a new version, and “Editing Published Record” when editing the metadata of an existing published version.

      • +
      +
    • +
    • Changed default publisher from “unknown” to “Knowledge Commons”

      +
        +
      • Previously, the default publisher was “unknown”. This was especially confusing for resource types where the publisher field is hidden on the upload form. Now, the default publisher is “Knowledge Commons”.

      • +
      +
    • +
    +
  • +
  • Solved collection links bug with custom routes

    +
      +
    • This is a back-end technical fix that should not be visible to users.

    • +
    +
  • +
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/README.html b/docs/build/README.html new file mode 100644 index 000000000..d2194b852 --- /dev/null +++ b/docs/build/README.html @@ -0,0 +1,336 @@ + + + + + + + + + About - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

About

+

Knowledge Commons Works is a collaborative tool for storing and sharing academic research. It is part of Knowledge Commons and is built on an instance of the InvenioRDM repository system.

+

Version 0.3.3-beta6

+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/site/CHANGES.md b/docs/build/_sources/CHANGES.md.txt similarity index 100% rename from site/CHANGES.md rename to docs/build/_sources/CHANGES.md.txt diff --git a/docs/build/_sources/README.md.txt b/docs/build/_sources/README.md.txt new file mode 100644 index 000000000..54f1d04a1 --- /dev/null +++ b/docs/build/_sources/README.md.txt @@ -0,0 +1,9 @@ +# About + +Knowledge Commons Works is a collaborative tool for storing and sharing academic research. It is part of Knowledge Commons and is built on an instance of the InvenioRDM repository system. + +Version 0.3.3-beta6 + +## Copyright + +Copyright 2023-24 Mesh Research. Released under the MIT license. (See the included LICENSE.txt file.) diff --git a/docs/build/_sources/cli_commands.md.txt b/docs/build/_sources/cli_commands.md.txt new file mode 100644 index 000000000..c81f7e29a --- /dev/null +++ b/docs/build/_sources/cli_commands.md.txt @@ -0,0 +1,63 @@ +# CLI Commands + +## Running Invenio CLI Commands + +InvenioRDM includes a number of CLI commands that can be run from the command line. These are invoked using the `invenio` command followed by the command name and any arguments. For example, to run the `invenio users create` command, you would use the following command: + +```shell +invenio users create --password +``` + +For a list of all available CLI commands, run the following command: +```shell +invenio --help +``` + +Note that the `invenio` command wraps the underlying `flask` CLI command, so any command that can be run with `flask` can also be run with `invenio`. + +## Running CLI Commands in the KCWorks Container + +Since the main KCWorks processes are run in docker containers, you will need to run the CLI commands inside the ui container (not the worker or api containers). + +To run a CLI command in the KCWorks container during local development, you can use the following command: +```shell +docker exec -it kcworks-ui bash +invenio +``` + +On the staging and production instances, the container name is generated dynamically whenever the service is deployed. You can find the correct name by running `docker ps | grep ui` command. Then run the CLI command inside that container: +```shell +docker exec -it bash +invenio +``` + +## KCWorks Custom CLI Commands + +KCWorks includes a number of custom CLI commands that are not part of the core InvenioRDM system. Further documentation can be found by running any command with the `--help` option. + +- `invenio importer` + - **provided by the `invenio-record-importer-kcworks` package** + - bulk imports records into the KCWorks instance. + - this provides the sub-commands: + - `invenio importer serialize`: serializes records from the legacy CORE database export into a JSON file suitable for import into the KCWorks instance. + - `invenio importer load`: loads serialized records from a JSON file into the KCWorks instance. + - `invenio importer read`: reads records from the data to be imported into the KCWorks instance. + - `invenio importer create-user`: creates a KCWorks user linked to a KC user. + - `invenio importer count-records`: counts the number of records in the data to be imported. + - `invenio importer delete-records`: deletes records from the KCWorks instance. + - `invenio importer create-stats`: creates usage stats aggregations for the imported records to correspond to the records' usage before import. + - `invenio importer aggregations`: aggregates the synthetic usage events for the imported records to produce usage stats for the imported records. + +- `invenio kcworks-index destroy` + - **provided by the main KCWorks package** (kcworks/site/cli.py) + - destroys search indices for the KCWorks instance that are *not* destroyed by the main KCWorks index destroy command. These are primarily the indices for storing usage events and aggregated usage data. + - **WARNING:** This data *only* exists in the OpenSearch indices. It is not backed up by the database and will be lost if the indices are destroyed. Use this command with extreme caution. + +- `invenio kcworks-users name-parts` + - **provided by the main KCWorks package** (kcworks/site/cli.py) + - either reads or updates how KCWorks will divide a user's name into parts (e.g., first name, last name, middle name, etc.) for display in the UI and in creating record metadata. + +- `invenio user-data update` + - **provided by the `invenio-remote-user-data-kcworks` package** + - updates a single user's data from the remote KC user data service. + - with the `--groups` option, updates a group collection's metadata from the remote KC group data service. diff --git a/docs/build/_sources/configuration.md.txt b/docs/build/_sources/configuration.md.txt new file mode 100644 index 000000000..c880984e2 --- /dev/null +++ b/docs/build/_sources/configuration.md.txt @@ -0,0 +1 @@ +# Configuration of InvenioRDM diff --git a/docs/build/_sources/customizations.md.txt b/docs/build/_sources/customizations.md.txt new file mode 100644 index 000000000..78625678c --- /dev/null +++ b/docs/build/_sources/customizations.md.txt @@ -0,0 +1,622 @@ +# Customizations to InvenioRDM + +## Template Customizations + +### Page templates + +### Email templates + +Custom email templates are located in `site/kcworks/templates/semantic-ui/invenio_notifications`. These override the default templates provided by InvenioRDM, and include both html and plaintext versions of each email, as well has markdown templates for other notification backends. + +Additional email templates are added for KCWorks-specific email types. + +- `user-first-record.create.jinja`: sent to KCWorks moderators when a user has created their first record. +- `user-first-record.publish.jinja`: sent to KCWorks moderators when a user's first record is published. + +## Record Detail Page Customizations + +### Modular Framework (invenio-modular-detail-page) + +### Overrides in the KCWorks Package (kcworks/site) + +## Deposit Form Customizations + +### Modular Framework (invenio-modular-deposit-form) + +### Overrides in the KCWorks Package (kcworks/site) + +## Collections + +### Collections for KC Groups (invenio-group-collections-kcworks) + +## Notifications + +### In-app notifications + +A user's unread notifications are tracked in the user's profile record. + +### Content moderation notifications + +#### User-first-record notifications + +Emails are sent to the KCWorks moderators when a user creates their first draft and publishes their first record. This is implemented using +- a custom service component for the RDMRecord service (kcworks.services.notifications.services.FirstRecordCreatedNotificationService) that runs during draft creation and publication and + - checks whether the user has any other drafts or published records. + - if not, adds a NotificationOp to the unit of work for the record operation to emit a notification of the type "user-first-record.create" or "user-first-record.publish". +- two custom notification builder classes (kcworks.services.notifications.builders.FirstRecordPublishedNotificationBuilder and kcworks.services.notifications.builders.FirstRecordCreatedNotificationBuilder) that build the notifications. + - these builders define the notification recipients using a custom ModeratorRoleRecipient generator (kcworks.services.notifications.generators.ModeratorRoleRecipient) and sends the notification to all users with the role defined in the NOTIFICATIONS_MODERATOR_ROLE config variable. + - they also define the notification backends to be used for sending the notification. In this case, a custom EmailBackend (kcworks.services.notifications.backends.EmailBackend) that sends email via the Flask-Mail extension. +- custom email templates for the notifications, located at `site/kcworks/templates/semantic-ui/invenio_notifications/`. + +## Integrations with KC + +### User Data Sync (invenio-remote-user-data-kcworks) + +User data is synced uni-directionally from KC to KCWorks. A user's data is synced with KC when +1. the user's SAML authentication info is first saved in KCWorks +2. the user logs into KCWorks +3. a webhook signal is received by KCWorks from KC + +### KC Search Provisioning (invenio-remote-api-provisioner) + +### SAML Authentication + +## Metadata Schema Customizations + +The default InvenioRDM metadata schema is defined in the `invenio-rdm-records` package and documented [here](https://inveniordm.docs.cern.ch/reference/metadata/). It also includes a number of optional metadata fields which have been enabled in KCWorks, documented [here](https://inveniordm.docs.cern.ch/reference/metadata/optional_metadata/). + +Beyond these InvenioRDM fields, KCWorks adds a number of custom metadata fields to the schema using InvenioRDM's custom field mechanism. These are all located in the top-level `custom_fields` field of the record metadata. They are prefixed with two different namespaces: +- `kcr`: custom fields that are used to store data from the KC system. These fields **may** be used for new data, but are not required. +- `hclegacy`: custom fields that are used to store data from the legacy CORE database. These fields **must not** be used for new data. + +### Notes about Implementation of Core InvenioRDM Fields + +#### metadata.subjects + +Note that KCWorks employs the FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) for the `subjects` field, complemented by the Homosaurus vocabulary (https://homosaurus.org/). + +The FAST vocabulary is divided into a number of sub-vocabularies called "facets", allowing more efficient searching and less ambiguity in the subject headings. FAST subjects in the `metadata.subjects` array must include the complete WorldCat url for the subject heading, the standard human-readable label, and a `scheme` including "FAST" followed by a hyphen and the FAST facet name in lowercase: i.e., one of +- "FAST-topical" +- "FAST-geographic" +- "FAST-corporate" +- "FAST-formgenre" +- "FAST-event" +- "FAST-meeting" +- "FAST-personal" +- "FAST-title" +- "FAST-chronological" + +You can search the FAST subject headings and their corresponding WorldCat urls [here](https://fast.oclc.org/searchfast). The OCLC also provides helpful tools such as assignFAST, which suggests FAST subject headings based on a string (https://fast.oclc.org/assignfast/) and a converter from LCSH subject headings to FAST subject (http://fast.oclc.org/lcsh2fast). + +Subject from the Homosaurus vocabulary must similarly include the complete homosaurus.org url as the `id`, the standard human-readable label as the `subject`, and a `scheme` with the value "Homosaurus". The Homosaurus subject headings can be searched [here](https://homosaurus.org/search/v3). + +Example: +```json +{ + "subjects": [ + { + "id": "http://id.worldcat.org/fast/123456", + "subject": "Art History", + "scheme": "FAST-topical" + }, + { + "id": "https://homosaurus.org/v3/homoit0000669", + "subject": "Intersex variations", + "scheme": "Homosaurus" + } + ] +} +``` + +#### metadata.creators/metadata.contributors + +Note that the KC username of a creator or contributor may be stored in the `person_or_org.identifiers` array of the creator or contributor object with the scheme `kc_username`. + +Users are also strongly encouraged to include an ORCID identifier in the `person_or_org.identifiers` array with the scheme `orcid`. + +> [!Note] +> The KC username is the primary link between a KCWorks record and a KC user. If you want a work to be associated with a KC user, you must include the KC username in creator or contributor object. + +Example: +```json +{ + "person_or_org": { + "identifiers": [ + { + "scheme": "kc_username", + "identifier": "jdoe" + }, + { + "scheme": "orcid", + "identifier": "0000-0000-0000-0000" + } + ] + } +} +``` + +### KCWorks Custom Fields (kcworks/site/metadata_fields) + +#### kcr:ai_usage + +Type: `Object[boolean, string]` + +This field stores data about any use of generative AI in the production of the record. + +Example: +```json +{ + "kcr:ai_usage": { + "ai_used": true, + "ai_description": "This paper was edited using generative AI editing software." + } +} +``` + +#### kcr:media + +Type: `Array[string]` + +This field stores a list of media or materials involved in the creation of the record. This field is used to store free-form user-defined descriptors of the media or materials and does not impose any controlled vocabulary. + +Example: +```json +{ + "kcr:media": ["watercolor", "found objects", "audio recordings"] +} +``` + +#### kcr:commons_domain + +Type: `string` + +This field stores the KC organizational (Commons) domain associated with the KCWorks record, if any. The record should also be placed in the KCWorks collection associated with this organization. + +Example: +```json +{ + "kcr:commons_domain": "arlisna.hcommons.org" +} +``` + +#### kcr:chapter_label + +Type: `string` + +This field stores the label of the chapter associated with the KCWorks record, if any. This allows us to differentiate between a simple chapter label (e.g. "Chapter 1") and a more substantive title for the same chapter (e.g., "The Role of AI in Modern Art"). + +Example: +```json +{ + "kcr:chapter_label": "Chapter 1" +} +``` + +#### kcr:content_warning + +Type: `string` + +This field stores an optional content warning for the KCWorks record. This is used to flag the record for KCWorks users so that they can be aware of potentially problematic content in the record. **This field is not to be used for content moderation by KCWorks moderators or admins. It is only to be used voluntarily and as desired by the record submitter.** + +Example: +```json +{ + "kcr:content_warning": "This work contains detailed accounts of abuse that may be distressing to some readers." +} +``` + +#### kcr:course_title + +Type: `string` + +This field stores the title of the course associated with the KCWorks record. It is intended primarily for use with syllabi and instructional materials. + +Example: +```json +{ + "kcr:course_title": "Introduction to Modern Art" +} +``` + +#### kcr:degree + +Type: `string` + +This field stores the educational degree (e.g., PhD, DPhil, MA, etc.) associated with the KCWorks record. It is intended primarily for use with theses and dissertations. + +Example: +```json +{ + "kcr:degree": "PhD" +} +``` + +#### kcr:discipline + +Type: `string` + +This field stores the academic discipline associated with the KCWorks record. It is intended primarily for use with theses, dissertations, and other educational artifacts. It is not intended as a general-purpose field for describing the subject matter of the KCWorks record. For that, you should use the `metadata.subjects` and `kcr:user_defined_tags` fields. + +This field is intended to complement the `thesis:university` and `kcr:institution_department` fields. + +This field is not constrained by any controlled vocabulary. + +Example: +```json +{ + "kcr:discipline": "Latin American Literature" +} +``` + +#### kcr:edition + +Type: `string` + +This field stores a descriptor for the edition of the KCWorks record, if any. + +Example: +```json +{ + "kcr:edition": "Second Edition" +} +``` + +#### kcr:meeting_organization + +Type: `string` + +This field stores the name of the organization associated with the meeting or conference associated with the KCWorks record. It is intended primarily for use with conference papers, presentations, proceedings, etc. + +Example: +```json +{ + "kcr:meeting_organization": "American Association of Art Historians" +} +``` + +#### kcr:project_title + +Type: `string` + +This field stores the title of a project for which the KCWorks record was created. It can be used flexibly for, e.g., grant-funded projects, research projects, artistic projects, etc. + +Example: +```json +{ + "kcr:project_title": "Kingston Poetry Residency, 2024" +} +``` + +#### kcr:publication_url + +Type: `string` (URL) + +This field stores the URL of the publication associated with the KCWorks record. It is *not* the URL of the KCWorks record itself or of the work it contains. For example, if the KCWorks record contains a journal article, it would *not* hold the URL for the published journal article. It is intended to hold the URL of the publication *as a whole* that the KCWorks record is based on or is a part of. So it might hold the main URL for the journal in which the article was published, or the main URL for the book in which the chapter was published, etc. + +This string must be a valid URL. + +Example: +```json +{ + "kcr:publication_url": "https://www.example.com/publication/123456" +} +``` + +#### kcr:sponsoring_institution + +Type: `string` + +This field stores the name of the institution that sponsored the KCWorks record. One intended use is for unpublished materials such white papers that were sponsored or commissioned by an institution. The field may also be used for the institution hosting a conference or workshop associated with the KCWorks record (as distinct from the organization that sponsored the event). + +Note that this field is not intended for the degree-granting institution associated with a thesis or dissertation. That institution's title should be stored in the `thesis:university` field. + +Example: +```json +{ + "kcr:sponsoring_institution": "University of Toronto" +} +``` + +#### kcr:submitter_email + +Type: `string` (email address) + +This field stores the email address of the submitter of the KCWorks record. It must be a valid email address. + +Example: +```json +{ + "kcr:submitter_email": "john.doe@example.com" +} +``` + +#### kcr:submitter_username + +Type: `string` + +This field stores the KC username of the submitter of the KCWorks record. This should be used even if the submitter is also a contributor to the KCWorks record and has included the same username in the `metadata.creators.person_or_org.identifiers` array. + +Example: +```json +{ + "kcr:submitter_username": "jdoe" +} +``` + +#### kcr:institution_department + +Type: `string` + +This field stores the institutional department in which a thesis, dissertation, or other educational artifact was produced. It is intended to complement the `thesis:university` field, which stores the degree-granting institution. + +Example: +```json +{ + "kcr:institution_department": "Art History" +} +``` + +#### kcr:book_series + +Type: `Object[string, string]` + +This field stores the title of a series that contains the KCWorks record, along with the optional volume number of the work within the series. + + +Example: +```json +{ + "kcr:book_series": { + "series_title": "The Complete Works of Jane Austen", + "series_volume": "Volume 1" + } +} +``` + +#### kcr:user_defined_tags + +Type: `Array[string]` + +This field stores a list of user-defined tags for the KCWorks record. Unlike the `metadata.subjects` field, these tags are not constrained by any controlled vocabulary. Items should be free-form strings that describe the KCWorks record in a way that is not covered by the `metadata.subjects` field. + +> [!Note] +> The `kcr:user_defined_tags` field is intended to supplement the `metadata.subjects` field, not as the primary means of describing the KCWorks record's subject matter. Assigning proper `metadata.subjects` entries allows for much more effective search and discovery of the KCWorks record. + +Example: +```json +{ + "kcr:user_defined_tags": ["Ukranian refugees", "Migrants in Europe"] +} +``` + +#### kcr:commons_search_recid (system field) + +This field is used to store the persistent identifier for the KCWorks record in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +#### kcr:commons_search_updated (system field) + +Type: `string` (ISO 8601 datetime string) + +This field stores the date and time when the KCWorks record was last updated in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +### HC Legacy Custom Fields + +The `hclegacy` namespace is used for custom fields that are used to store data from the legacy CORE database. These fields should not be used for new data. + +#### custom_fields.hclegacy:groups_for_deposit + +Type: `Array[Object[string, string]]` + +This field is used to store the groups to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks collections during migration. + +Example: +```json +{ + "hclegacy:groups_for_deposit": [ + { + "group_name": "Group Name", + "group_identifier": "Group Identifier" + } + ] +} +``` + +#### custom_fields.hclegacy:collection + +Type: `string` + +This field is used to store the org collection to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration. + +Example: +```json +{ + "hclegacy:collection": "Collection Name" +} +``` + +#### custom_fields.hclegacy:committee_deposit + +Type: `integer` + +This field is used to store the committee deposit number for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:committee_deposit": 123456 +} +``` + +#### custom_fields.hclegacy:file_location + +Type: `string` + +This field is used to store the relative path the the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_location": "/path/to/file.pdf" +} +``` + +#### custom_fields.hclegacy:file_pid + +Type: `string` + +This field is used to store the persistent identifier for the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_pid": "hc:123456" +} +``` + +#### custom_fields.hclegacy:previously_published + +Type: `string` + +This field is used to store the previously published status for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:previously_published": "true" +} +``` + +#### custom_fields.hclegacy:publication_type + +Type: `string` + +This field is used to store the publication type for a legacy CORE record. It was used during migration to help determine the KCWorks resource type of the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:publication_type": "Journal Article" +} +``` + +#### custom_fields.hclegacy:record_change_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the last change to a legacy CORE record. It was not used during migration to KCWorks and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_change_date": "2024-01-01T00:00:00Z" +} +``` + +#### custom_fields.hclegacy:record_creation_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the creation of a legacy CORE record. It was not used during migration because InvenioRDM does not allow overriding of the record creation date. It is only preserved for historical purposes and should not be used for new data. + +Example: +```json +{ + "hclegacy:record_creation_date": "2024-01-01T00:00:00Z" +} +``` + +#### custom_fields.hclegacy:record_identifier + +Type: `string` + +This field is used to store the internal system identifier for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_identifier": "1001634-1263" +} +``` + +#### custom_fields.hclegacy:submitter_org_memberships + +Type: `array[string]` + +This field is used to store the organizations to which a legacy CORE record's submitter belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration and assign the work to those org collections. + +Example: +```json +{ + "hclegacy:submitter_org_memberships": ["arlisna", "mla"] +} +``` + +#### custom_fields.hclegacy:submitter_affiliation + +Type: `string` + +This field is used to store the organizational affiliation of a legacy CORE record's submitter at the time of import into KCWorks. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_affiliation": "University of Toronto" +} +``` + +#### custom_fields.hclegacy:submitter_id + +Type: `string` + +This field is used to store the internal KC system user id of a legacy CORE record's submitter. It was used during migration to assign ownership of the newly created record, and is preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_id": "123456" +} +``` + +#### custom_fields.hclegacy:total_views + +Type: `integer` + +This field is used to store the total number of views for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_views": 123456 +} +``` + +#### custom_fields.hclegacy:total_downloads + +Type: `integer` + +This field is used to store the total number of downloads for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_downloads": 123456 +} +``` + +## Bulk Record Import (invenio-record-importer-kcworks) + +## Forked Core Invenio Modules + +### invenio-communities + +### invenio-rdm-records + +### invenio-records-resources + +### invenio-vocabularies diff --git a/docs/build/_sources/developing.md.txt b/docs/build/_sources/developing.md.txt new file mode 100644 index 000000000..b0b3834d5 --- /dev/null +++ b/docs/build/_sources/developing.md.txt @@ -0,0 +1,259 @@ +# Developing KCWorks + +## Version Numbering + +KCWorks uses semantic versioning (https://semver.org/). When a new release is made, the version number should be incremented in the following files: + +- `README.md` +- `docs/source/README.md` +- `docs/source/conf.py` +- `site/pyproject.toml` +- `site/kcworks/__init__.py` + +While in beta, the version number should be followed by a numbered `-beta` suffix: e.g., `0.3.3-beta6`. This suffix should be updated continuously (without starting over again for minor releases) until version 1.0.0 is reached and KCWorks leaves beta. + +Bug fixes and other changes that do not introduce new features (including changes to documentation, build processes, etc.) should be considered `patch` releases. + +New features should be considered `minor` releases. + +## Version Control + +### Git Branching Strategy + +KCWorks employs a modified version of the Gitlab Flow branching strategy for version control. The repository has four persistent branches: + +- `main` is the default branch and is the reference point for active development. It will usually not be ready for production deployment. +- `staging` is the branch that is deployed to the staging server. It is created from the `main` branch when changes are ready to be tested. No commits should be made directly to the `staging` branch except to merge changes from `main`. +- `production` is the branch that is deployed to the development server. It is created from the `staging` branch when changes are ready to be deployed to the production server. No commits should be made directly to the `production` branch except to merge changes from `staging`. +- `gh_pages` is the branch that is used to generate the static documentation site for KCWorks on Github Pages. This branch is automatically updated from the `main` branch. + +New changes should be made to the `main` branch or to a temporary `feature` or `bugfix` branch created from the `main` branch. These temporary branches should be merged back into `main` as often as possible, and the temporary branches deleted. + +No commits should be made directly to the `staging` or `production` branches. All changes should be made to the `main` branch and then merged into `staging` and `production` via pull requests. This is especially important because changes pushed to `staging` and `production` branches will be automatically uploaded to the respective servers. + +### Commit strategy + +Wherever possible, a commit should represent a single completed change. We try to avoid `wip` commits in order to keep the commit history readable. + +In practice, though, we will often need to make incremental commits, particularly on feature and bugfix branches. The practice should be to squash all of the related commits into a single commit before merging the changes into `main`. + +### Naming Commits + +### Tagging Releases + +Whenever the KCWorks version number changes, it that commit should be tagged with the new version number. This can be done by running the following command: + +```shell +git tag -a -m "Release " +``` +We do not create branches for each numbered release. + +### Git Submodules + +KCWorks uses git submodules to manage dependencies. The submodules are located in the `site/kcworks/dependencies` folder. The submodules are cloned from the upstream repositories when the KCWorks instance is first created. They are updated from the upstream repositories when the KCWorks instance is updated. + +Note that in some cases there are inter-dependencies between these submodules. For example, the `invenio-record-importer-kcworks` submodule has its own dependency on the `invenio-group-collections-kcworks` submodule. When cloning the KCWorks repository, you **should not use the `--recurse-submodules` option** because this will clone redundant copies of these inter-dependent submodules. Instead, you should clone the KCWorks repository and then initialize the submodules in a separate step with `git submodule update --init`. Likewise, when updating the KCWorks submodules, you should use the `git submodule update --remote` command **without the `--recursive` option**. + + + +## Updating the running KCWorks instance with development changes + +### Changes to html template files + +Changes to html template files will be visible immediately in the running Knowledge Commons Works instance. You simply need to refresh the page in your browser. + +If you add a new template file (including overriding an existing template file), you will need to collect the new file into the central templates folder and restart the uwsgi processes. This can be done by running the following command inside the `web-ui` container: + +```shell +invenio collect -v +uwsgi --reload /tmp/uwsgi_ui.pid +``` +Then refresh your browser. + +### Changes to invenio.cfg + +Changes to the invenio.cfg file will only take effect after the instance uwsgi processes are restarted. This can be done by running the following command inside the `web-ui` container: +```shell +uwsgi --reload /tmp/uwsgi_ui.pid +``` +Or you can restart the docker-compose project, which will also restart the uwsgi processes. + +### Changes to theme (CSS) and javascript files + +#### The basic build process (slow) + +Invenio employs a build process for css and javascript files. Changes to these files will not be visible in the running Knowledge Commons Works instance until the build process is run. This can be done by running the following command inside the `web-ui` container: + +```shell +bash ./scripts/build-assets.sh +``` + +#### Rebuilding changed files on the fly (fast but limited) + +The problem is that this build process takes a long time to run, especially in the containers. For most tasks, you can instead run the following command to watch for changes to the files and automatically rebuild them: + +```shell +invenio webpack run start +``` + +The file watching will continue until you stop it with CTRL-C. It will continue to occupy the terminal window where you started it. This means that you can see it respond and begin integrating changed files when it finds them. You can also see there any error or warning output from the build process--very helpful for debugging. + +> [!Note] +> The watch command will only pick up changes to files that already existed during the last Webpack build. If you add +> - a new javascript file +> - a new css (less) file +> - a new node.js package requirement +> then you need to again run the basic (slow) build script to include it in the build process. +> After that you can run `invenio webpack run start` again to pick up changes on the fly. + +### Adding new node.js packages to be included + +Normally, the node.js packages to be included in a project are listed in that project's package.json file. In the case of InvenioRDM, the package.json file is created dynamically by InvenioRDM each time the build process runs. So you cannot directly modify the package.json file in your instance folder. Instead, you must add the package to the package.json file in the InvenioRDM module that requires it. Unless you are creating a new stand-alone extension, this will mean adding the package to the `webpack.py` file in the `knowledge-commons-works/sites/kcworks` folder. + +There you will find a `WebpackThemeBundle` object that defines your bundle of js and style files along with their dependencies. If I wanted to add the `geopattern` package to the project, I would add it to the `dependencies` dictionary in the `WebpackThemeBundle` object like this: + +```python + +theme = WebpackThemeBundle( + __name__, + "assets", + default="semantic-ui", + themes={ + "semantic-ui": dict( + entry={ + "custom_pdf_viewer_js": "./js/invenio_custom_pdf_viewer" + "/pdfjs.js", + }, + dependencies={ + "geopattern": "^1.2.3", + }, + aliases={ + /* ... */ + }, + ), + }, +) +``` + +If you add a new node.js package to the project, you will then need to run the build script inside the `web-ui` container to install it: + +```shell +bash ./scripts/build-assets.sh +``` + +### Changes to static files + +Changes to static files like images will require running the collect command to copy them to the central static folder. This can be done by running the following command inside the `web-ui` container: + +```shell +invenio collect -v +``` + +You will then need to restart the uwsgi processes or restart the docker-compose project as described above. + +### Changes to python code in the `site` folder + +Changes to python code in the `site` folder should (like changes to template files) take effect immediately in the running Knowledge Commons Works instance. You simply need to refresh the page in your browser. + +#### Adding new entry points + +Sometimes you will need to add new entry points to inform the Flask application about additional code you have provided. This is done via the `setup.py` file in the `site` folder. Once you have added the entry point declaration, you will need to re-install the `kcworks` package in the `kcworks-ui`, `kcworks-api`, and `kcworks-worker` container. This can be done by running the following command inside the each container: + +```shell +cd /opt/invenio/src/site +pip install -e . +uwsgi --reload /tmp/uwsgi_ui.pid +``` + +If you have added js, css, or static files along with the entry point code, you will also need to run the collect and webpack build commands as described above and restart the docker-compose project. + +Note that entry point changes may be overridden if you pull a more recent version of the kcworks docker image and restart the docker-compose project. Ultimately the entry point changes will have to be added to a new version of the kcworks docker image. + +### Changes to external python modules (including Invenio modules) + +Changes to other python modules (including Invenio modules) will require rebuilding the main kcworks container. Additions to the python requirements should be added to the `Pipfile` in the kcworks folder and committed to the Github repository. You should then request that the kcworks container be rebuilt with the additions. + +In the meantime, required python packages can be installed directly in the `kcworks-ui`, `kcworks-api`, and `kcworks-worker` containers. Enter each container and then install the required package pip (not pipenv): + +```shell +pip install +``` + +## Digging deeper + +What follows is a step-by-step walk through this process. + +> [!Note] +> These instructions do not support installation under Windows. Windows users should emulate a Linux environment using WSL2. + +## Updating an Instance with Upstream Changes + +If changes have been made to the upstream Knowledge Commons Works repository and the kcworks container, you will need to update your local instance to reflect those changes. This process involves pulling the changes from the upstream repository, pulling the latest version of the kcworks docker image, restarting the docker-compose project with recreated containers, and rebuilding the asset files. + +1. First, from the root knowledge-commons-works folder, pull the changes from the upstream git repository: + +```shell +git pull origin main +``` + +2. Then pull the latest version of the kcworks docker image: + +```shell +docker pull monotasker/kcworks:latest +``` + +3. Next, restart the docker-compose project with recreated containers: + +```shell +docker-compose --file docker-compose.yml stop +docker-compose --file docker-compose.yml up -d --build --force-recreate +``` + +4. Clean up leftover containers and images: + +```shell +docker system prune -a +``` + +> [!Caution] +> Make sure that you run this `prune` command *while the containers are running.* If you run it while the containers are stopped, you will delete the containers and images that you need to run the application, as well as volumes with stored data. + +6. Rebuild the asset files with the following command: + +```shell +docker exec -it kcworks-ui bash +bash ./scripts/build-assets.sh +``` + +7. Then refresh your browser to see the changes. + +## Running automated tests (NEEDS UPDATING) + +Automated tests (unit tests and integration tests) are run every time a commit is pushed to the knowledge-commons-works Github repo. You can (and should) also run the test suite locally. + +There are currently two distinct sets of tests that have to be run separately: python tests run using invenio's fixtures, and javascript tests run separately using jest. + +### Python tests + +The python test suite includes (a) unit tests for back end code, (b) tests of ui views and api requests run with a client fixture, (c) user interaction tests run with selenium webdriver. To run the unit tests and view/request tests, navigate to the root knowledge-commons-works folder and run +```console +pipenv run pytest +``` +By default the selenium browser interaction tests are not run. To include these, run pytest with the E2E environment variable set to "yes": +```console +pipenv run E2E=yes pytest +``` +Running the selenium tests also requires that you have the Selenium Client and Chrome Webdriver installed locally. + +### Javascript tests + +Pytest does not directly test custom javascript files or React components. In order to test these, navigate to the root knowledge-commons-works folder and run +```console +npm run test +``` +These tests are run using the jest test runner, configured in the packages.json file in the root knowledge-commons-works folder. + +Note that these tests run using a local npm configuration in the knowledge-commons-works folder. Any packages that are normally available to InvenioRDM must be added to the local package.json configuration and will be installed in the local node_modules folder. Since this folder is not included in GIT version control, before you run the javascript tests you must ensure the required packages are installed locally by running +```console +npm install +``` diff --git a/docs/build/_sources/in_depth.md.txt b/docs/build/_sources/in_depth.md.txt new file mode 100644 index 000000000..5662bfa20 --- /dev/null +++ b/docs/build/_sources/in_depth.md.txt @@ -0,0 +1,348 @@ +# In-depth Installation Instructions (NEEDS UPDATING) + +## Install Python and Required Python Tools + +### Ensure some version of python is installed + +Most operating systems (especially MacOS and Linux) will already have a version of Python installed. You can proceed directly to the next step. + +### Install pyenv and pipenv + +First install the **pyenv** tool to manage python versions, and the **pipenv** tool to manage virtual environments. (There are other tools to use for virtual environment management, but InvenioRDM is built to work with pipenv.) + +Instructions for Linux, MacOS, and Windows can be found here: https://www.newline.co/courses/create-a-serverless-slackbot-with-aws-lambda-and-python/installing-python-3-and-pyenv-on-macos-windows-and-linux + +### Install and enable Python 3.9.16 + +Invenio's command line tools require a specific python version to work reliably. Currently this is python 3.9.16. At the command line, first install this python version using pyenv: +```console +pyenv install 3.9.16 +``` +Note: It is important to use cpython. Invenio does not support other python interpreters (like pypy) and advises against using anaconda python in particular for running the RDM application. + +Just because this python version is installed does not guarantee it will be used. Next, navigate to the directory where you cloned the source code, and set the correct python version to be used locally: + +```console +cd ~/path/to/directory/knowledge-commons-works +pyenv local 3.9.16 +``` + +#### Install the invenio-cli command line tool + +From the same directory Use pip to install the **invenio-cli** python package. (Do not use pipenv yet or create a virtual environment.) + +```console +pip install invenio-cli +``` + +## Install Docker 20.10.10+ and Docker-compose 1.17.0+ + +### Linux + +If you are using Ubuntu Linux, follow the steps for installing Docker and Docker-compose explained here: https://linux.how2shout.com/install-and-configure-docker-compose-on-ubuntu-22-04-lts-jammy/ + +You must then create a `docker` group and add the current user to it (so that you can run docker commands without sudo). This is *required* for the invenio-cli scripts to work, and it must be done for the *same user* that will run the cli commands: + +```console +sudo usermod --append --groups docker $USER +``` + +You will likely want to configure Docker to start on system boot with systemd. + +### MacOS + +If you are using MacOS, follow the steps for installing Docker desktop explained here: https://docs.docker.com/desktop/install/mac-install/ + +You will then need to ensure Docker has enough memory to run all the InvenioRDM containers. In the Docker Desktop app, + +- click settings cog icon (top bar near right) +- set the memory slider under the "Resources" tab manually to at least 6-8GB + +Note: The environment variable recommended in the InvenioRDM documentation for MacOS 11 Big Sur is *not* necessary for newer MacOS versions. + +### Fixing docker-compose "not found" error + +With the release of compose v2, the command syntax changed from `docker-compose` to `docker compose` (a command followed by a sub-command instead of one hyphenated command). This will break the invenio-cli scripts, which use the `docker-compose` command and you will receive an error asking you to install the "docker-compose" package. + +One solution on Linux systems is to install Docker Compose standalone, which uses the old `docker-compose` syntax: + +```console +sudo curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose +``` + +Another approach is simply to alias the `docker compose` command to `docker-compose` in the configuration file for your command line shell (.bashrc, .zshrc, or whichever config file is used by your shell). + +See further https://docs.docker.com/compose/install/other/ + +### Docker log rotation + +Regardless of your operating system, you should set up log rotation for containers to keep the size of logging files from getting out of control. Either set your default logging driver to "local" (which rotates log files automatically) or set logging configuration if you use the "json-file" logging driver. See https://docs.docker.com/config/containers/logging/configure/ + +### Note about docker contexts + +Make sure to always use the same Docker context to run all of the containers for InvenioRDM. See further, https://docs.docker.com/engine/context/working-with-contexts/ + +## Install Node.js and NVM + +Currently InvenioRDM (v. 11) requires Node.js version 16.19.1. The best way to install and manage Node.js versions is using the nvm version manager. You can find instructions here: https://www.freecodecamp.org/news/node-version-manager-nvm-install-guide/ + +Once nvm is installed, install the required Node.js version and set it as the active version: +```console +nvm install v16.19.1 +nvm use 16.19.1 +``` +You may have other Node versions installed as well, so before a session working with Knowledge Commons Works it's a good idea to make sure you're using the correct version. On MacOS and Linux you can check +from the command line with +```console +which node +``` + +## Clone the knowledge-commons-works Code + +Using GIT, clone this repository. You should then have a folder called `knowledge-commons-works` (unless you chose to name it something else) on your local computer. + +(add-and-configure-an-environment-file)= +## Add and Configure an Environment File + +### Standardized environment variables + +This file must include the following variables with these values: + +``` +INVENIO_INSTANCE_PATH=/opt/invenio/var/instance +INVENIO_RECORD_IMPORTER_LOCAL_DATA_DIR=/ +INVENIO_RECORD_IMPORTER_DATA_DIR=/opt/invenio/var/import_data +INVENIO_SEARCH_DOMAIN='search:9200' +INVENIO_SITE_UI_URL="https://localhost" +INVENIO_SITE_API_URL="https://localhost/api" +REDIS_DOMAIN='cache:6379' +INVENIO_SQLALCHEMY_DATABASE_URI="postgresql+psycopg2://kcworks:kcworks@db/kcworks" +POSTGRES_USER=kcworks +POSTGRES_DB=kcworks +``` + +The INVENIO_INSTANCE_PATH should be set to the full path of the instance directory where InvenioRDM will store its compiled files. Since KC Works runs inside containers, this is normally a standard folder inside the container file systems (/opt/invenio/var/instance). If you were to run InvenioRDM with the python/uwsgi processes installed on your local machine, this would be a folder inside your local virtual environment folder. For example, on MacOS this might be ~/.local/share/virtualenvs/{virtual env name}/var/instance/. + +### Variables for local credentials + +Several variables hold random values used to secure the application, or hold passwords and email addresses supplied by the local developer: + +``` +INVENIO_CSRF_SECRET_SALT='..put a long random value here..' +INVENIO_SECURITY_LOGIN_SALT='..put a long random value here..' +INVENIO_SECRET_KEY=CHANGE_ME +POSTGRES_PASSWORD=??? +PGADMIN_DEFAULT_EMAIL=??? +PGADMIN_DEFAULT_PASSWORD=??? +``` + +Random values for secrets like INVENIO_SECRET_KEY can be generated in a terminal by running +```console +python -c 'import secrets; print(secrets.token_hex())' +``` +#### Additional environment variables with sensitive information + +Additionally, you should add the following variables with the appropriate values obtained from the Commons administrators: + +``` +COMMONS_API_TOKEN=mytoken # this must be obtained from the Commons administrators +COMMONS_SEARCH_API_TOKEN=mytoken # this must be obtained from the Commons administrators +INVENIO_DATACITE_PASSWORD=myinveniodatacitepassword # this must be obtained from the Commons administrators +``` +You will also need to enter the following variable with a dummy value and then replace it with the actual value after the instance is set up. Once you have an administrative user, you can generate a token for that user in the KC Works admin ui and enter it here: + +``` +API_TOKEN=myapitoken +``` + +#### Additional required environment variables with paths on your local file system + +The next variables refer to paths on your local file system that are used during local development to provide easy access to the source code of various python packages and KCWorks modules: + +``` +PYTHON_LOCAL_GIT_PACKAGES_PATH=/path/to/local/git/packages +PYTHON_LOCAL_SITE_PACKAGES_PATH=/path/to/local/virtual/environment/lib/python3.12/site-packages +``` + +PYTHON_LOCAL_GIT_PACKAGES_PATH is the parent directory that holds cloned packages that aren't available via pip or that have been forked by us. If you are not working with the KCWorks custom modules locally, this can be set to the folder where you cloned the KCWorks code. Otherwise, it should be the path to the parent folder containing the git repositories for the forked Invenio modules and the extra KC Works modules. + +PYTHON_LOCAL_SITE_PACKAGES_PATH is the path to the site-packages folder in your local virtual environment. This assumes that you have run `pipenv install --dev --python=3.12` in your KCWorks project folder to install the python packages locally in a virtual environment. + +## Install the Invenio Python Modules + +Navigate to the root knowledge-commons-works folder and run +```console +pipenv install --dev --python=3.12 +``` +Note: This installation step will take several minutes. + +This stage +- creates and initializes a Python virtual environment using pipenv +- locks the python package requirements +- installs the Invenio python packages (with pipenv) + - these packages are again installed under your virtual environment folder. On MacOS this is often ~/.local/share/virtualenvs/{virtual env name}/lib/python3.9/site-packages/. You will find several modules installed here with names that start with "invenio_". +- installs the `kcworks` Python package (with pipenv) + - alongside the Invenio packages you will also find a `kcworks` package containing any custom extensions to InvenioRDM defined in your `knowledge-commons-works/sites/` folder +- installs required python dependencies (with pipenv) + +## Build and Configure the Containerized Services + +### Build and start the containers + +Make sure you are in the root knowledge-commons-works folder and then run +```console +docker-compose up -d +``` +This step will +- build the docker image for the nginx web server (frontend) using ./docker/nginx/Dockerfile +- pull remote images for other services: mq, search, db, cache, pgadmin, opensearch-dashboards +- start containers from all of these images and mounts local files or folders into the containers as required in the docker-compose.yml and docker-services.yml files + +### Create and initialize the database, search indices, and task queue + +Again, from the root knowledge-commons-works folder, run this command: +```console +invenio-cli services setup +``` + +This step will +- create the postgresql database and table structure +- create Invenio admin role and assigns it superuser access +- begin indexing with OpenSearch +- create Invenio fixtures +- insert demo data into the database (unless you add the --no-demo-data flag) + +Note: If for some reason you need to run this step again, you will need to add the `--force` flag to the `docker-compose` command. This tells Invenio to destroy any existing redis cache, database, index, and task queue before recreating them all. Just be aware that performing this setup again with `--force` will **destroy all data in your database and all OpenSearch indices**. + +### Start the uwsgi applications and celery worker + +Finally, you need to start the actual applications. Knowledge Commons Works is actually run as two separate applications: one providing an html user interface, and one providing a REST api and serving JSON responses. Each application is served to the nginx web server by its own uwsgi process. The nginx server begins automatically when the `frontend` docker container starts, but the uwsgi applications run on your local machine and need to be started directly. + +These applications are also supported by a Celery worker process. This is a task queue that (with the help of the RabbitMQ docker container) frees up the python applications from being blocked by long-running tasks like indexing. The celery worker also runs on your local machine and must be started directly. + +If you want to quickly start all of these processes in the background (as daemons), you can run the kcr-startup.sh script in the root knowledge-commons-works directory: +```console +bash kcr-startup.sh +``` +The processes will output request and error logging to files in the `logs` folder of your knowledge-commons-works folder. + +To stop these processes, simply run +```console +bash kcr-shutdown.sh +``` + +If you would like to view the real time log output of these processes, you can also start them individually in three separate terminals: +```console +pipenv run celery --app invenio_app.celery worker --beat --events --loglevel INFO +``` +```console +pipenv run uwsgi docker/uwsgi/uwsgi_ui.ini --pidfile=/tmp/kcr_ui.pid +``` +```console +pipenv run uwsgi docker/uwsgi/uwsgi_rest.ini --pidfile=/tmp/kcr_api.pid +``` +These processes can be stopped individually by pressing CTRL-C + +### Create an admin user + +From the command line, run these commands to create and activate the admin user: +```console +pipenv run invenio users create --password +pipenv run invenio users activate +``` +If you want this user to have access to the administration panel in Invenio, you also need to run +```console +pipenv run invenio access allow administration-access user +``` + +## Use the application! + +You should now be able to access the following: +- The Knowledge Commons Works app (https://localhost) +- The Knowledge Commons Works REST api (https://localhost/api) +- pgAdmin for database management (https://localhost/pgadmin) +- Opensearch Dashboards for managing search (https://localhost:5601) + +### Controlling the Application Services + +Once Knowledge Commons Works is installed, you can manage its services from the command line. **Note: Unless otherwise specified, the commands below must be run from the root knowledge-commons-works folder.** + +### Startup and shutdown scripts + +The bash script kcr-startup.sh will start + - the containerized services (if not running) + - the celery worker + - the two uwsgi processes +It will also ensure that you have a .env file and copy your set your INVENIO_INSTANCE_PATH variable in that file to your local instance folder, matching the instance_path variable in your .invenio.private file. + +Simply navigate to the root knowledge-commons-works folder and run +```console +bash ./kcr-startup.sh +``` + +To stop the processes and containerized services, simply run +```console +bash ./kcr-shutdown.sh +``` + +### Controlling just the containerized services + +If you want to stop or start just the containerized services (rather than the local processes), you can use the invenio cli: +```console +invenio-cli services start +invenio-cli services stop +``` +Or you can control them directly with the docker-compose command: +```console +docker-compose up -d +docker-compose stop +``` +Note that stopping the containers this way will not destroy the data and configuration which live in docker volumes. Those volumes persist as long as the containers are not destroyed. **Do not use the `docker-compose down` command unless you want the containers to be destroyed.** + +### View logging output for uwsgi processes + +Activity and error logging for the two uwsgi processes are written to date-stamped files in the knowledge-commons-works/logs/ folder. To watch the live logging output from one of these processes, open a new terminal in your knowledge-commons-works folder and run +```console +tail -f logs/uwsgi-ui-{date}.log +``` +or +```console +tail -f logs/uwsgi-api-{date}.log +``` + +### View container logging output + +The logging output (and stdout) can be viewed with Docker Desktop using its convenient ui. It can also be viewed from the command line using: + +```console +docker logs -f +``` + +The names of the various images are: +- nginx: kcworks-frontend-1 +- RabbitMQ: kcworks-mq-1 +- PostgreSQL: kcworks-db-1 +- OpenSearch: kcworks-search-1 +- Redis: kcworks-cache-1 +- OpenSearch Dashboards: kcworks-opensearch-dashboards-1 +- pgAdmin: kcworks-pgadmin-1 + +### Controlling containerized nginx server + +The frontend container is configured so that the configuration files in docker/nginx/ are bind mounted. This means that changes to those config files can be seen in the running container and enabled without rebuilding the container. To reload the nginx configuration, first **enter the frontend container**: +```console +docker exec -it kcworks-frontend-1 bash +``` +Then tell gninx to reload the config files: +```console +nginx -s reload +``` +You can also test the nginx config prior to reloading by running +```console +nginx -t +``` +Alternately, you can rebuild and restart the frontend container by running +```console +docker-compose up -d --build frontend +``` diff --git a/docs/build/_sources/index.rst.txt b/docs/build/_sources/index.rst.txt new file mode 100644 index 000000000..0f57de54e --- /dev/null +++ b/docs/build/_sources/index.rst.txt @@ -0,0 +1,30 @@ +.. Knowledge Commons Works documentation master file, created by + sphinx-quickstart on Mon Jan 6 17:53:27 2025. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Knowledge Commons Works's documentation! +=================================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + README + CHANGES + installation + metadata + customizations + configuration + cli_commands + infrastructure + developing + in_depth + reference + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/build/_sources/infrastructure.md.txt b/docs/build/_sources/infrastructure.md.txt new file mode 100644 index 000000000..f598357a1 --- /dev/null +++ b/docs/build/_sources/infrastructure.md.txt @@ -0,0 +1 @@ +# KCWorks Infrastructure diff --git a/docs/build/_sources/installation.md.txt b/docs/build/_sources/installation.md.txt new file mode 100644 index 000000000..5dbeb497d --- /dev/null +++ b/docs/build/_sources/installation.md.txt @@ -0,0 +1,121 @@ +# Installation + +## Quickstart + +These instructions allow you to run Knowledge Commons Works for local development. The app source files are copied onto your system, but the Flask application and other services (database, search, etc.) are run in Docker containers. The application is served to your browser by an nginx web server running in a separate container. + +First you will need to have the correct versions of Docker (20.10.10+ with Docker Compose 1.17.0+) and Python (3.12.0+ with pipenv). + +From there, installation involves these steps. Each one is further explained below, but here is a quick reference: + +### 1. Clone the git repository + +- From your command line, navigate to the parent folder where you want the cloned repository code to live +- Clone the knowledge-commons-works repository with `git clone git@github.com:MESH-Research/knowledge-commons-works.git && git submodule update --init` + +> **Note**: Do not use the `--recurse-submodules` option when cloning the repository or the `--recursive` option when initializing the submodules. This will clone redundant copies of the inter-dependent submodules. + +### 2. Create your configuration files + +- `cd knowledge-commons-works` +- Create and configure the `.env` file in this folder as described {ref}`here ` +- Create the `.invenio.private` file with the following contents: + +```shell +[cli] +services_setup = True +instance_path = /opt/invenio/var/instance +``` +### 3. Start the docker-compose project + +- `docker-compose --file docker-compose.yml up -d` + +### 4. Initialize the database and other services, and build asset files + +- enter the `web-ui` container by running `docker exec -it kcworks-ui bash` + +> **Note**: The container name may be different depending on your local docker setup. You can find the correct name by running `docker ps` + +- run the script to set up the instance services and build static assets `bash ./scripts/setup-services.sh` + +> **Note**: Some of the commands in this script may take a while to run. Patience is required! The `invenio rdm-records fixtures` command in particular may take up to an hour to complete during which time it provides no feedback. Don't despair! It is working. + +### 5. Create your own admin user + +- enter the `web-ui` container by running `docker exec -it kcworks-ui bash` + +> **Note**: The container name may be different depending on your local docker setup. You can find the correct name by running `docker ps` + +- run the commands: + +```shell +invenio users create --password +invenio users activate +invenio access allow administration-access user +``` + +### 6. View the application + +- The Knowledge Commons Works app is now running at `https://localhost` +- The REST API is running at `https://localhost/api` +- pgAdmin is running at `https://localhost/pgadmin` +- OpenSearch Dashboards is running at `https://localhost:5601` + +This setup will allow you to make changes to the core Knowledge Commons Works codebase and see those changes reflected in the running application. + +## Full local development setup + +You will need to take some further steps if you want to + - Make and test changes to the various invenio modules that are included as git submodules. + - View and insert debugging statements into the code of the various core Invenio packages installed into the python environment. +To do this, you will need to do the following: + +1. Ensure the required git submodules are cloned by running the following commands in the `knowledge-commons-works` folder: + ```shell + git submodule update --init + ``` + This will clone the following repositories: + ```shell + main git@github.com:MESH-Research/invenio-record-importer-kcworks.git + main git@github.com:MESH-Research/invenio-group-collections-kcworks.git + main git@github.com:MESH-Research/invenio-modular-deposit-form.git + main git@github.com:MESH-Research/invenio-modular-detail-page.git + main git@github.com:MESH-Research/invenio-remote-api-provisioner.git + main git@github.com:MESH-Research/invenio-remote-user-data-kcworks.git + local-working git@github.com:MESH-Research/invenio-communities.git + local-working git@github.com:MESH-Research/invenio-rdm-records.git + local-working git@github.com:MESH-Research/invenio-records-resources.git + local-working git@github.com:MESH-Research/invenio-vocabularies.git + ``` + These cloned repositories should then appear under the `knowledge-commons-works/site/kcworks/dependencies` folder. +2. Install the python packages required by Knowldge Commons Works locally by running `pipenv install` in the `knowledge-commons-works` folder. +3. When you start up the docker compose project, add an additional project file to the command: + - `docker-compose --file docker-compose.yml --file docker-compose.dev.yml up -d` +This will mount a variety of local package folders as bind mounts in your running containers. This will allow you to make changes to the python code in the cloned repositories and see those changes reflected in the running Knowledge Commons Works instance. + +## Controlling the KCWorks (Flask) application + +The application instance and its services can be started and stopped by starting and stopping the docker-compose project: + +```shell +docker-compose --file docker-compose.yml up -d +``` +```shell +docker-compose --file docker-compose.yml stop +``` + +> [!Caution] +> Do not use the `docker-compose down` command unless you want the containers to be destroyed. This will destroy all data in your database and all OpenSearch indices. YOU DO NOT WANT TO DO THIS! + +If you need to restart the main Flask application (e.g., after making configuration changes) you can do so either by stopping and restarting the docker-compose project or by running the following command inside the `kcworks-ui` container: + +```shell +uwsgi --reload /tmp/uwsgi_ui.pid +``` + +Similarly, the REST API can be restarted by running the following command inside the `web-ui` container: + +```shell +uwsgi --reload /tmp/uwsgi_api.pid +``` +But these commands should not be necessary in normal operation. diff --git a/docs/build/_sources/metadata.md.txt b/docs/build/_sources/metadata.md.txt new file mode 100644 index 000000000..b653bf5cf --- /dev/null +++ b/docs/build/_sources/metadata.md.txt @@ -0,0 +1,807 @@ +# Metadata Schema and Vocabularies + +The default metadata schema for InvenioRDM records is defined in the `invenio-rdm-records` package and documented [here](https://inveniordm.docs.cern.ch/reference/metadata/). It also includes a number of optional metadata fields which have been enabled in KCWorks, documented [here](https://inveniordm.docs.cern.ch/reference/metadata/optional_metadata/). + +Beyond these InvenioRDM fields, KCWorks adds a number of custom metadata fields to the schema using InvenioRDM's custom field mechanism. These are all located in the top-level `custom_fields` field of the record metadata. They are prefixed with two different namespaces: + +- `kcr`: custom fields that are used to store data from the KC system. These fields **may** be used for new data, but are not required. +- `hclegacy`: custom fields that are used to store data from the legacy CORE repository. These fields **must not** be used for new data. + +## Example JSON record + +What follows is an example of a complete metadata record (JSON object) used to create a KCWorks record. The various fields and their possible values are described in the sections below. + +Note that no single actual record would include all of these fields. The example is provided to illustrate the structure of the metadata record and the sort of values that are valid for each field. + +```json +{ + "custom_fields": { + "code:codeRepository": "https://github.com/my-project", + "code:programmingLanguage": ["Python", "JavaScript"], + "code:developmentStatus": "active", + "journal:journal": { + "title": "My Journal Title", + "issue": "2", + "volume": "8", + "pages": "123-456", + "issn": "0378-5955" + }, + "imprint:imprint": { + "title": "My Book Title", + "pages": "458", + "isbn": "0-06-251587-X", + "place": "Lagos" + }, + "meeting:meeting": { + "dates": "October 2022", + "place": "Michigan State University", + "title": "Fall 2022 Meeting of the Humanities Commons Working Group", + "acronym": "MET", + "url": "https://myevent.org" + }, + "kcr:ai_usage": { + "ai_used": true, + "ai_description": "I used ChatGPT to generate the references." + }, + "kcr:book_series": [ + { + "series_title": "My series", + "series_volume": "8" + } + ], + "kcr:commons_domain": "hcommons.org", + "kcr:course_title": "My course", + "kcr:degree": "PhD", + "kcr:discipline": "Education", + "kcr:edition": "2nd", + "kcr:institution_department": "Education", + "kcr:media": [ + "printed paper" + ], + "kcr:meeting_organization": "Humanities Commons", + "kcr:notes": "These are some notes about the deposit not intended for the public record.", + "kcr:project_title": "My project", + "kcr:publication_url": "https://mycourse.org", + "kcr:sponsoring_institution": "MSU", + "kcr:submitter_email": "jane.doe@hcommons.org", + "kcr:submitter_username": "janedoe", + "kcr:volumes": { + "total_volumes": "8", + "volume": "1" + }, + "kcr:user_defined_tags": [ + "Access", + "Digital humanities", + "Collaboration" + ] + }, + "metadata": { + "resource_type": { + "id": "instructionalResource-syllabus" + }, + "creators": [ + { + "person_or_org": { + "name": "Doe, Jane", + "type": "personal", + "given_name": "Jane", + "family_name": "Doe", + "identifiers": [ + { + "scheme": "orcid", + "identifier": "0000-0001-2345-6789" + } + ] + }, + "role": { + "id": "author" + }, + "affiliations": [{"name": "Michigan State University"}] + } + ], + "title": "A Syllabus for a Digital Pedagogy Course", + "additional_titles": [ + { + "title": "Teaching in the Age of AI", + "type": { "id": "subtitle" }, + "lang": { "id": "eng" } + } + ], + "publisher": "KCWorks", + "publication_date": "2018/2020-09", + "subjects": [ + { + "id": "http://id.worldcat.org/fast/958235", + "subject": "History", + "scheme": "FAST-topical" + }, + { + "id": "http://id.worldcat.org/fast/1086436", + "subject": "Race", + "scheme": "FAST-topical" + }, + { + "id": "http://id.worldcat.org/fast/966892", + "subject": "Identity (Psychology)", + "scheme": "FAST-topical" + } + ], + "contributors": [ + { + "person_or_org": { + "name": "John Doe", + "type": "personal", + "given_name": "John", + "family_name": "Doe", + "identifiers": [ + { + "scheme": "orcid", + "identifier": "0000-0001-2345-6780" + } + ] + }, + "role": { "id": "other" }, + "affiliations": [{"name": "Michigan State University"}] + } + ], + "dates": [ + { + "date": "2025-01-01", + "type": { "id": "other" }, + "description": "The date when the syllabus was made available." + } + ], + "formats": [ + "application/pdf" + ], + "languages": [ + { "id": "eng" } + ], + "identifiers": [ + { + "identifier": "https://example.com/syllabus", + "scheme": "url" + } + ], + "related_identifiers": [ + { + "identifier": "10.1234/foo.bar", + "scheme": "doi", + "relation_type": { "id": "iscitedby" }, + "resource_type": { "id": "dataset" } + } + ], + "sizes": [ + "11 pages", + "32 x 24 cm" + ], + "version": "v1.0", + "rights": [ + { + "id": "cc-by-nc-4.0", + "description": { + "en": "Allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited and that the re-use is not for commercial purposes." + }, + "link": "https://creativecommons.org/licenses/by-nc/4.0/legalcode" + } + ], + "description": "

A description

with HTML tags

", + "additional_descriptions": [ + { + "description": "Some additional description about the methods involved in the syllabus.", + "type": { + "id": "methods", + "title": { + "de": "Technische Informationen", + "en": "Technical info" + } + }, + "lang": {"id": "eng", "title": {"en": "English"}} + } + ], + "locations": { + "features": [ + { + "geometry": { + "type": "Point", + "coordinates": [-32.94682, -60.63932] + }, + "place": "test location place", + "description": "test location description", + "identifiers": [ + {"identifier": "12345abcde", "scheme": "wikidata"}, + {"identifier": "12345abcde", "scheme": "geonames"} + ] + } + ] + }, + "funding": [ + { + "funder": { + "id": "00k4n6c32", + }, + "award": { + "identifiers": [ + { + "identifier": "https://sandbox.zenodo.org/", + "scheme": "url" + } + ], + "number": "111023", + "title": { + "en": "Launching of the research program on meaning processing" + } + } + } + ], + }, + "access": { + "record": "public", + "files": "restricted", + "embargo": { + "active": true, + "until": "2029-01-01", + "reason": "Publisher requires embargo.", + } + }, +} +``` + +## Controlled Vocabularies + +### Subject headings + +#### FAST + +The FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) is used for the `subjects` field. + +#### Homosaurus + +The FAST vocabulary is augmented in KCWorks by the Homosaurus vocabulary (https://homosaurus.org/) for subjects related to sexuality and gender identity. + +### Organizations + +#### ROR + +The Research Organization Registry (https://ror.org/) is used for the `organizations` field. + + +## Notes about Implementation of Core InvenioRDM Fields + +### metadata.subjects + +Note that KCWorks employs the FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) for the `subjects` field, complemented by the Homosaurus vocabulary (https://homosaurus.org/). + +The FAST vocabulary is divided into a number of sub-vocabularies called "facets", allowing more efficient searching and less ambiguity in the subject headings. FAST subjects in the `metadata.subjects` array must include the complete WorldCat url for the subject heading, the standard human-readable label, and a `scheme` including "FAST" followed by a hyphen and the FAST facet name in lowercase: i.e., one of +- "FAST-topical" +- "FAST-geographic" +- "FAST-corporate" +- "FAST-formgenre" +- "FAST-event" +- "FAST-meeting" +- "FAST-personal" +- "FAST-title" +- "FAST-chronological" + +You can search the FAST subject headings and their corresponding WorldCat urls [here](https://fast.oclc.org/searchfast). The OCLC also provides helpful tools such as assignFAST, which suggests FAST subject headings based on a string (https://fast.oclc.org/assignfast/) and a converter from LCSH subject headings to FAST subject (http://fast.oclc.org/lcsh2fast). + +Subject from the Homosaurus vocabulary must similarly include the complete homosaurus.org url as the `id`, the standard human-readable label as the `subject`, and a `scheme` with the value "Homosaurus". The Homosaurus subject headings can be searched [here](https://homosaurus.org/search/v3). + +Example: +```json +{ + "subjects": [ + { + "id": "http://id.worldcat.org/fast/123456", + "subject": "Art History", + "scheme": "FAST-topical" + }, + { + "id": "https://homosaurus.org/v3/homoit0000669", + "subject": "Intersex variations", + "scheme": "Homosaurus" + } + ] +} +``` + +### metadata.creators/metadata.contributors + +Note that the KC username of a creator or contributor may be stored in the `person_or_org.identifiers` array of the creator or contributor object with the scheme `kc_username`. + +Users are also strongly encouraged to include an ORCID identifier in the `person_or_org.identifiers` array with the scheme `orcid`. + +> [!Note] +> The KC username is the primary link between a KCWorks record and a KC user. If you want a work to be associated with a KC user, you must include the KC username in creator or contributor object. + +Example: +```json +{ + "person_or_org": { + "identifiers": [ + { + "scheme": "kc_username", + "identifier": "jdoe" + }, + { + "scheme": "orcid", + "identifier": "0000-0000-0000-0000" + } + ] + } +} +``` + +### KCWorks Custom Fields (kcworks/site/metadata_fields) + +#### kcr:ai_usage + +Type: `Object[boolean, string]` + +This field stores data about any use of generative AI in the production of the record. + +Example: +```json +{ + "kcr:ai_usage": { + "ai_used": true, + "ai_description": "This paper was edited using generative AI editing software." + } +} +``` + +#### kcr:media + +Type: `Array[string]` + +This field stores a list of media or materials involved in the creation of the record. This field is used to store free-form user-defined descriptors of the media or materials and does not impose any controlled vocabulary. + +Example: +```json +{ + "kcr:media": ["watercolor", "found objects", "audio recordings"] +} +``` + +#### kcr:commons_domain + +Type: `string` + +This field stores the KC organizational (Commons) domain associated with the KCWorks record, if any. The record should also be placed in the KCWorks collection associated with this organization. + +Example: +```json +{ + "kcr:commons_domain": "arlisna.hcommons.org" +} +``` + +#### kcr:chapter_label + +Type: `string` + +This field stores the label of the chapter associated with the KCWorks record, if any. This allows us to differentiate between a simple chapter label (e.g. "Chapter 1") and a more substantive title for the same chapter (e.g., "The Role of AI in Modern Art"). + +Example: +```json +{ + "kcr:chapter_label": "Chapter 1" +} +``` + +#### kcr:content_warning + +Type: `string` + +This field stores an optional content warning for the KCWorks record. This is used to flag the record for KCWorks users so that they can be aware of potentially problematic content in the record. **This field is not to be used for content moderation by KCWorks moderators or admins. It is only to be used voluntarily and as desired by the record submitter.** + +Example: +```json +{ + "kcr:content_warning": "This work contains detailed accounts of abuse that may be distressing to some readers." +} +``` + +#### kcr:course_title + +Type: `string` + +This field stores the title of the course associated with the KCWorks record. It is intended primarily for use with syllabi and instructional materials. + +Example: +```json +{ + "kcr:course_title": "Introduction to Modern Art" +} +``` + +#### kcr:degree + +Type: `string` + +This field stores the educational degree (e.g., PhD, DPhil, MA, etc.) associated with the KCWorks record. It is intended primarily for use with theses and dissertations. + +Example: +```json +{ + "kcr:degree": "PhD" +} +``` + +#### kcr:discipline + +Type: `string` + +This field stores the academic discipline associated with the KCWorks record. It is intended primarily for use with theses, dissertations, and other educational artifacts. It is not intended as a general-purpose field for describing the subject matter of the KCWorks record. For that, you should use the `metadata.subjects` and `kcr:user_defined_tags` fields. + +This field is intended to complement the `thesis:university` and `kcr:institution_department` fields. + +This field is not constrained by any controlled vocabulary. + +Example: +```json +{ + "kcr:discipline": "Latin American Literature" +} +``` + +#### kcr:edition + +Type: `string` + +This field stores a descriptor for the edition of the KCWorks record, if any. + +Example: +```json +{ + "kcr:edition": "Second Edition" +} +``` + +#### kcr:meeting_organization + +Type: `string` + +This field stores the name of the organization associated with the meeting or conference associated with the KCWorks record. It is intended primarily for use with conference papers, presentations, proceedings, etc. + +Example: +```json +{ + "kcr:meeting_organization": "American Association of Art Historians" +} +``` + +#### kcr:project_title + +Type: `string` + +This field stores the title of a project for which the KCWorks record was created. It can be used flexibly for, e.g., grant-funded projects, research projects, artistic projects, etc. + +Example: +```json +{ + "kcr:project_title": "Kingston Poetry Residency, 2024" +} +``` + +#### kcr:publication_url + +Type: `string` (URL) + +This field stores the URL of the publication associated with the KCWorks record. It is *not* the URL of the KCWorks record itself or of the work it contains. For example, if the KCWorks record contains a journal article, it would *not* hold the URL for the published journal article. It is intended to hold the URL of the publication *as a whole* that the KCWorks record is based on or is a part of. So it might hold the main URL for the journal in which the article was published, or the main URL for the book in which the chapter was published, etc. + +This string must be a valid URL. + +Example: +```json +{ + "kcr:publication_url": "https://www.example.com/publication/123456" +} +``` + +#### kcr:sponsoring_institution + +Type: `string` + +This field stores the name of the institution that sponsored the KCWorks record. One intended use is for unpublished materials such white papers that were sponsored or commissioned by an institution. The field may also be used for the institution hosting a conference or workshop associated with the KCWorks record (as distinct from the organization that sponsored the event). + +Note that this field is not intended for the degree-granting institution associated with a thesis or dissertation. That institution's title should be stored in the `thesis:university` field. + +Example: +```json +{ + "kcr:sponsoring_institution": "University of Toronto" +} +``` + +#### kcr:submitter_email + +Type: `string` (email address) + +This field stores the email address of the submitter of the KCWorks record. It must be a valid email address. + +Example: +```json +{ + "kcr:submitter_email": "john.doe@example.com" +} +``` + +#### kcr:submitter_username + +Type: `string` + +This field stores the KC username of the submitter of the KCWorks record. This should be used even if the submitter is also a contributor to the KCWorks record and has included the same username in the `metadata.creators.person_or_org.identifiers` array. + +Example: +```json +{ + "kcr:submitter_username": "jdoe" +} +``` + +#### kcr:institution_department + +Type: `string` + +This field stores the institutional department in which a thesis, dissertation, or other educational artifact was produced. It is intended to complement the `thesis:university` field, which stores the degree-granting institution. + +Example: +```json +{ + "kcr:institution_department": "Art History" +} +``` + +#### kcr:book_series + +Type: `Object[string, string]` + +This field stores the title of a series that contains the KCWorks record, along with the optional volume number of the work within the series. + + +Example: +```json +{ + "kcr:book_series": { + "series_title": "The Complete Works of Jane Austen", + "series_volume": "Volume 1" + } +} +``` + +#### kcr:user_defined_tags + +Type: `Array[string]` + +This field stores a list of user-defined tags for the KCWorks record. Unlike the `metadata.subjects` field, these tags are not constrained by any controlled vocabulary. Items should be free-form strings that describe the KCWorks record in a way that is not covered by the `metadata.subjects` field. + +> [!Note] +> The `kcr:user_defined_tags` field is intended to supplement the `metadata.subjects` field, not as the primary means of describing the KCWorks record's subject matter. Assigning proper `metadata.subjects` entries allows for much more effective search and discovery of the KCWorks record. + +Example: +```json +{ + "kcr:user_defined_tags": ["Ukranian refugees", "Migrants in Europe"] +} +``` + +#### kcr:commons_search_recid (system field) + +This field is used to store the persistent identifier for the KCWorks record in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +#### kcr:commons_search_updated (system field) + +Type: `string` (ISO 8601 datetime string) + +This field stores the date and time when the KCWorks record was last updated in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +### HC Legacy Custom Fields + +The `hclegacy` namespace is used for custom fields that are used to store data from the legacy CORE database. These fields should not be used for new data. + +#### custom_fields.hclegacy:groups_for_deposit + +Type: `Array[Object[string, string]]` + +This field is used to store the groups to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks collections during migration. + +Example: +```json +{ + "hclegacy:groups_for_deposit": [ + { + "group_name": "Group Name", + "group_identifier": "Group Identifier" + } + ] +} +``` + +#### custom_fields.hclegacy:collection + +Type: `string` + +This field is used to store the org collection to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration. + +Example: +```json +{ + "hclegacy:collection": "Collection Name" +} +``` + +#### custom_fields.hclegacy:committee_deposit + +Type: `integer` + +This field is used to store the committee deposit number for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:committee_deposit": 123456 +} +``` + +#### custom_fields.hclegacy:file_location + +Type: `string` + +This field is used to store the relative path the the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_location": "/path/to/file.pdf" +} +``` + +#### custom_fields.hclegacy:file_pid + +Type: `string` + +This field is used to store the persistent identifier for the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_pid": "hc:123456" +} +``` + +#### custom_fields.hclegacy:previously_published + +Type: `string` + +This field is used to store the previously published status for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:previously_published": "true" +} +``` + +#### custom_fields.hclegacy:publication_type + +Type: `string` + +This field is used to store the publication type for a legacy CORE record. It was used during migration to help determine the KCWorks resource type of the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:publication_type": "Journal Article" +} +``` + +#### custom_fields.hclegacy:record_change_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the last change to a legacy CORE record. It was not used during migration to KCWorks and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_change_date": "2024-01-01T00:00:00Z" +} +``` + +#### custom_fields.hclegacy:record_creation_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the creation of a legacy CORE record. It was not used during migration because InvenioRDM does not allow overriding of the record creation date. It is only preserved for historical purposes and should not be used for new data. + +Example: +```json +{ + "hclegacy:record_creation_date": "2024-01-01T00:00:00Z" +} +``` + +#### custom_fields.hclegacy:record_identifier + +Type: `string` + +This field is used to store the internal system identifier for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_identifier": "1001634-1263" +} +``` + +#### custom_fields.hclegacy:submitter_org_memberships + +Type: `array[string]` + +This field is used to store the organizations to which a legacy CORE record's submitter belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration and assign the work to those org collections. + +Example: +```json +{ + "hclegacy:submitter_org_memberships": ["arlisna", "mla"] +} +``` + +#### custom_fields.hclegacy:submitter_affiliation + +Type: `string` + +This field is used to store the organizational affiliation of a legacy CORE record's submitter at the time of import into KCWorks. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_affiliation": "University of Toronto" +} +``` + +#### custom_fields.hclegacy:submitter_id + +Type: `string` + +This field is used to store the internal KC system user id of a legacy CORE record's submitter. It was used during migration to assign ownership of the newly created record, and is preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_id": "123456" +} +``` + +#### custom_fields.hclegacy:total_views + +Type: `integer` + +This field is used to store the total number of views for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_views": 123456 +} +``` + +#### custom_fields.hclegacy:total_downloads + +Type: `integer` + +This field is used to store the total number of downloads for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_downloads": 123456 +} +``` diff --git a/docs/build/_sources/reference.md.txt b/docs/build/_sources/reference.md.txt new file mode 100644 index 000000000..0b77fdd69 --- /dev/null +++ b/docs/build/_sources/reference.md.txt @@ -0,0 +1,5 @@ +# Reference + +## InvenioRDM Documentation + +The Knowledge Commons Works is built as an instance of InvenioRDM. The InvenioRDM Documentation, including customization and development information, can be found at https://inveniordm.docs.cern.ch/. \ No newline at end of file diff --git a/docs/build/_static/alabaster.css b/docs/build/_static/alabaster.css new file mode 100644 index 000000000..e3174bf93 --- /dev/null +++ b/docs/build/_static/alabaster.css @@ -0,0 +1,708 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar { + max-height: 100%; + overflow-y: auto; +} + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 160px; +} + +div.sphinxsidebar .search > div { + display: table-cell; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Hide ugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/docs/build/_static/basic.css b/docs/build/_static/basic.css new file mode 100644 index 000000000..f316efcb4 --- /dev/null +++ b/docs/build/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/build/_static/custom.css b/docs/build/_static/custom.css new file mode 100644 index 000000000..2a924f1d6 --- /dev/null +++ b/docs/build/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/docs/build/_static/debug.css b/docs/build/_static/debug.css new file mode 100644 index 000000000..74d4aec33 --- /dev/null +++ b/docs/build/_static/debug.css @@ -0,0 +1,69 @@ +/* + This CSS file should be overridden by the theme authors. It's + meant for debugging and developing the skeleton that this theme provides. +*/ +body { + font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji"; + background: lavender; +} +.sb-announcement { + background: rgb(131, 131, 131); +} +.sb-announcement__inner { + background: black; + color: white; +} +.sb-header { + background: lightskyblue; +} +.sb-header__inner { + background: royalblue; + color: white; +} +.sb-header-secondary { + background: lightcyan; +} +.sb-header-secondary__inner { + background: cornflowerblue; + color: white; +} +.sb-sidebar-primary { + background: lightgreen; +} +.sb-main { + background: blanchedalmond; +} +.sb-main__inner { + background: antiquewhite; +} +.sb-header-article { + background: lightsteelblue; +} +.sb-article-container { + background: snow; +} +.sb-article-main { + background: white; +} +.sb-footer-article { + background: lightpink; +} +.sb-sidebar-secondary { + background: lightgoldenrodyellow; +} +.sb-footer-content { + background: plum; +} +.sb-footer-content__inner { + background: palevioletred; +} +.sb-footer { + background: pink; +} +.sb-footer__inner { + background: salmon; +} +.sb-article { + background: white; +} diff --git a/docs/build/_static/doctools.js b/docs/build/_static/doctools.js new file mode 100644 index 000000000..4d67807d1 --- /dev/null +++ b/docs/build/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/docs/build/_static/documentation_options.js b/docs/build/_static/documentation_options.js new file mode 100644 index 000000000..5abb8afc8 --- /dev/null +++ b/docs/build/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.3.3', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/docs/build/_static/file.png b/docs/build/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/docs/build/_static/language_data.js b/docs/build/_static/language_data.js new file mode 100644 index 000000000..367b8ed81 --- /dev/null +++ b/docs/build/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/docs/build/_static/minus.png b/docs/build/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/docs/build/_static/plus.png b/docs/build/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/docs/build/_static/pygments.css b/docs/build/_static/pygments.css new file mode 100644 index 000000000..f71bfbfc9 --- /dev/null +++ b/docs/build/_static/pygments.css @@ -0,0 +1,258 @@ +.highlight pre { line-height: 125%; } +.highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8F5902; font-style: italic } /* Comment */ +.highlight .err { color: #A40000; border: 1px solid #EF2929 } /* Error */ +.highlight .g { color: #000 } /* Generic */ +.highlight .k { color: #204A87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000 } /* Literal */ +.highlight .n { color: #000 } /* Name */ +.highlight .o { color: #CE5C00; font-weight: bold } /* Operator */ +.highlight .x { color: #000 } /* Other */ +.highlight .p { color: #000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8F5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8F5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8F5902; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #8F5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8F5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8F5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A40000 } /* Generic.Deleted */ +.highlight .ge { color: #000; font-style: italic } /* Generic.Emph */ +.highlight .ges { color: #000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #EF2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8F5902 } /* Generic.Prompt */ +.highlight .gs { color: #000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #A40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204A87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204A87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204A87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204A87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204A87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204A87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000 } /* Literal.Date */ +.highlight .m { color: #0000CF; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4E9A06 } /* Literal.String */ +.highlight .na { color: #C4A000 } /* Name.Attribute */ +.highlight .nb { color: #204A87 } /* Name.Builtin */ +.highlight .nc { color: #000 } /* Name.Class */ +.highlight .no { color: #000 } /* Name.Constant */ +.highlight .nd { color: #5C35CC; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #CE5C00 } /* Name.Entity */ +.highlight .ne { color: #C00; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000 } /* Name.Function */ +.highlight .nl { color: #F57900 } /* Name.Label */ +.highlight .nn { color: #000 } /* Name.Namespace */ +.highlight .nx { color: #000 } /* Name.Other */ +.highlight .py { color: #000 } /* Name.Property */ +.highlight .nt { color: #204A87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000 } /* Name.Variable */ +.highlight .ow { color: #204A87; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000; font-weight: bold } /* Punctuation.Marker */ +.highlight .w { color: #F8F8F8 } /* Text.Whitespace */ +.highlight .mb { color: #0000CF; font-weight: bold } /* Literal.Number.Bin */ +.highlight .mf { color: #0000CF; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000CF; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000CF; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000CF; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sa { color: #4E9A06 } /* Literal.String.Affix */ +.highlight .sb { color: #4E9A06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4E9A06 } /* Literal.String.Char */ +.highlight .dl { color: #4E9A06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8F5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4E9A06 } /* Literal.String.Double */ +.highlight .se { color: #4E9A06 } /* Literal.String.Escape */ +.highlight .sh { color: #4E9A06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4E9A06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4E9A06 } /* Literal.String.Other */ +.highlight .sr { color: #4E9A06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4E9A06 } /* Literal.String.Single */ +.highlight .ss { color: #4E9A06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465A4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000 } /* Name.Function.Magic */ +.highlight .vc { color: #000 } /* Name.Variable.Class */ +.highlight .vg { color: #000 } /* Name.Variable.Global */ +.highlight .vi { color: #000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000 } /* Name.Variable.Magic */ +.highlight .il { color: #0000CF; font-weight: bold } /* Literal.Number.Integer.Long */ +@media not print { +body[data-theme="dark"] .highlight pre { line-height: 125%; } +body[data-theme="dark"] .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight .hll { background-color: #404040 } +body[data-theme="dark"] .highlight { background: #202020; color: #D0D0D0 } +body[data-theme="dark"] .highlight .c { color: #ABABAB; font-style: italic } /* Comment */ +body[data-theme="dark"] .highlight .err { color: #A61717; background-color: #E3D2D2 } /* Error */ +body[data-theme="dark"] .highlight .esc { color: #D0D0D0 } /* Escape */ +body[data-theme="dark"] .highlight .g { color: #D0D0D0 } /* Generic */ +body[data-theme="dark"] .highlight .k { color: #6EBF26; font-weight: bold } /* Keyword */ +body[data-theme="dark"] .highlight .l { color: #D0D0D0 } /* Literal */ +body[data-theme="dark"] .highlight .n { color: #D0D0D0 } /* Name */ +body[data-theme="dark"] .highlight .o { color: #D0D0D0 } /* Operator */ +body[data-theme="dark"] .highlight .x { color: #D0D0D0 } /* Other */ +body[data-theme="dark"] .highlight .p { color: #D0D0D0 } /* Punctuation */ +body[data-theme="dark"] .highlight .ch { color: #ABABAB; font-style: italic } /* Comment.Hashbang */ +body[data-theme="dark"] .highlight .cm { color: #ABABAB; font-style: italic } /* Comment.Multiline */ +body[data-theme="dark"] .highlight .cp { color: #FF3A3A; font-weight: bold } /* Comment.Preproc */ +body[data-theme="dark"] .highlight .cpf { color: #ABABAB; font-style: italic } /* Comment.PreprocFile */ +body[data-theme="dark"] .highlight .c1 { color: #ABABAB; font-style: italic } /* Comment.Single */ +body[data-theme="dark"] .highlight .cs { color: #E50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body[data-theme="dark"] .highlight .gd { color: #FF3A3A } /* Generic.Deleted */ +body[data-theme="dark"] .highlight .ge { color: #D0D0D0; font-style: italic } /* Generic.Emph */ +body[data-theme="dark"] .highlight .ges { color: #D0D0D0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body[data-theme="dark"] .highlight .gr { color: #FF3A3A } /* Generic.Error */ +body[data-theme="dark"] .highlight .gh { color: #FFF; font-weight: bold } /* Generic.Heading */ +body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */ +body[data-theme="dark"] .highlight .go { color: #CCC } /* Generic.Output */ +body[data-theme="dark"] .highlight .gp { color: #AAA } /* Generic.Prompt */ +body[data-theme="dark"] .highlight .gs { color: #D0D0D0; font-weight: bold } /* Generic.Strong */ +body[data-theme="dark"] .highlight .gu { color: #FFF; text-decoration: underline } /* Generic.Subheading */ +body[data-theme="dark"] .highlight .gt { color: #FF3A3A } /* Generic.Traceback */ +body[data-theme="dark"] .highlight .kc { color: #6EBF26; font-weight: bold } /* Keyword.Constant */ +body[data-theme="dark"] .highlight .kd { color: #6EBF26; font-weight: bold } /* Keyword.Declaration */ +body[data-theme="dark"] .highlight .kn { color: #6EBF26; font-weight: bold } /* Keyword.Namespace */ +body[data-theme="dark"] .highlight .kp { color: #6EBF26 } /* Keyword.Pseudo */ +body[data-theme="dark"] .highlight .kr { color: #6EBF26; font-weight: bold } /* Keyword.Reserved */ +body[data-theme="dark"] .highlight .kt { color: #6EBF26; font-weight: bold } /* Keyword.Type */ +body[data-theme="dark"] .highlight .ld { color: #D0D0D0 } /* Literal.Date */ +body[data-theme="dark"] .highlight .m { color: #51B2FD } /* Literal.Number */ +body[data-theme="dark"] .highlight .s { color: #ED9D13 } /* Literal.String */ +body[data-theme="dark"] .highlight .na { color: #BBB } /* Name.Attribute */ +body[data-theme="dark"] .highlight .nb { color: #2FBCCD } /* Name.Builtin */ +body[data-theme="dark"] .highlight .nc { color: #71ADFF; text-decoration: underline } /* Name.Class */ +body[data-theme="dark"] .highlight .no { color: #40FFFF } /* Name.Constant */ +body[data-theme="dark"] .highlight .nd { color: #FFA500 } /* Name.Decorator */ +body[data-theme="dark"] .highlight .ni { color: #D0D0D0 } /* Name.Entity */ +body[data-theme="dark"] .highlight .ne { color: #BBB } /* Name.Exception */ +body[data-theme="dark"] .highlight .nf { color: #71ADFF } /* Name.Function */ +body[data-theme="dark"] .highlight .nl { color: #D0D0D0 } /* Name.Label */ +body[data-theme="dark"] .highlight .nn { color: #71ADFF; text-decoration: underline } /* Name.Namespace */ +body[data-theme="dark"] .highlight .nx { color: #D0D0D0 } /* Name.Other */ +body[data-theme="dark"] .highlight .py { color: #D0D0D0 } /* Name.Property */ +body[data-theme="dark"] .highlight .nt { color: #6EBF26; font-weight: bold } /* Name.Tag */ +body[data-theme="dark"] .highlight .nv { color: #40FFFF } /* Name.Variable */ +body[data-theme="dark"] .highlight .ow { color: #6EBF26; font-weight: bold } /* Operator.Word */ +body[data-theme="dark"] .highlight .pm { color: #D0D0D0 } /* Punctuation.Marker */ +body[data-theme="dark"] .highlight .w { color: #666 } /* Text.Whitespace */ +body[data-theme="dark"] .highlight .mb { color: #51B2FD } /* Literal.Number.Bin */ +body[data-theme="dark"] .highlight .mf { color: #51B2FD } /* Literal.Number.Float */ +body[data-theme="dark"] .highlight .mh { color: #51B2FD } /* Literal.Number.Hex */ +body[data-theme="dark"] .highlight .mi { color: #51B2FD } /* Literal.Number.Integer */ +body[data-theme="dark"] .highlight .mo { color: #51B2FD } /* Literal.Number.Oct */ +body[data-theme="dark"] .highlight .sa { color: #ED9D13 } /* Literal.String.Affix */ +body[data-theme="dark"] .highlight .sb { color: #ED9D13 } /* Literal.String.Backtick */ +body[data-theme="dark"] .highlight .sc { color: #ED9D13 } /* Literal.String.Char */ +body[data-theme="dark"] .highlight .dl { color: #ED9D13 } /* Literal.String.Delimiter */ +body[data-theme="dark"] .highlight .sd { color: #ED9D13 } /* Literal.String.Doc */ +body[data-theme="dark"] .highlight .s2 { color: #ED9D13 } /* Literal.String.Double */ +body[data-theme="dark"] .highlight .se { color: #ED9D13 } /* Literal.String.Escape */ +body[data-theme="dark"] .highlight .sh { color: #ED9D13 } /* Literal.String.Heredoc */ +body[data-theme="dark"] .highlight .si { color: #ED9D13 } /* Literal.String.Interpol */ +body[data-theme="dark"] .highlight .sx { color: #FFA500 } /* Literal.String.Other */ +body[data-theme="dark"] .highlight .sr { color: #ED9D13 } /* Literal.String.Regex */ +body[data-theme="dark"] .highlight .s1 { color: #ED9D13 } /* Literal.String.Single */ +body[data-theme="dark"] .highlight .ss { color: #ED9D13 } /* Literal.String.Symbol */ +body[data-theme="dark"] .highlight .bp { color: #2FBCCD } /* Name.Builtin.Pseudo */ +body[data-theme="dark"] .highlight .fm { color: #71ADFF } /* Name.Function.Magic */ +body[data-theme="dark"] .highlight .vc { color: #40FFFF } /* Name.Variable.Class */ +body[data-theme="dark"] .highlight .vg { color: #40FFFF } /* Name.Variable.Global */ +body[data-theme="dark"] .highlight .vi { color: #40FFFF } /* Name.Variable.Instance */ +body[data-theme="dark"] .highlight .vm { color: #40FFFF } /* Name.Variable.Magic */ +body[data-theme="dark"] .highlight .il { color: #51B2FD } /* Literal.Number.Integer.Long */ +@media (prefers-color-scheme: dark) { +body:not([data-theme="light"]) .highlight pre { line-height: 125%; } +body:not([data-theme="light"]) .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight .hll { background-color: #404040 } +body:not([data-theme="light"]) .highlight { background: #202020; color: #D0D0D0 } +body:not([data-theme="light"]) .highlight .c { color: #ABABAB; font-style: italic } /* Comment */ +body:not([data-theme="light"]) .highlight .err { color: #A61717; background-color: #E3D2D2 } /* Error */ +body:not([data-theme="light"]) .highlight .esc { color: #D0D0D0 } /* Escape */ +body:not([data-theme="light"]) .highlight .g { color: #D0D0D0 } /* Generic */ +body:not([data-theme="light"]) .highlight .k { color: #6EBF26; font-weight: bold } /* Keyword */ +body:not([data-theme="light"]) .highlight .l { color: #D0D0D0 } /* Literal */ +body:not([data-theme="light"]) .highlight .n { color: #D0D0D0 } /* Name */ +body:not([data-theme="light"]) .highlight .o { color: #D0D0D0 } /* Operator */ +body:not([data-theme="light"]) .highlight .x { color: #D0D0D0 } /* Other */ +body:not([data-theme="light"]) .highlight .p { color: #D0D0D0 } /* Punctuation */ +body:not([data-theme="light"]) .highlight .ch { color: #ABABAB; font-style: italic } /* Comment.Hashbang */ +body:not([data-theme="light"]) .highlight .cm { color: #ABABAB; font-style: italic } /* Comment.Multiline */ +body:not([data-theme="light"]) .highlight .cp { color: #FF3A3A; font-weight: bold } /* Comment.Preproc */ +body:not([data-theme="light"]) .highlight .cpf { color: #ABABAB; font-style: italic } /* Comment.PreprocFile */ +body:not([data-theme="light"]) .highlight .c1 { color: #ABABAB; font-style: italic } /* Comment.Single */ +body:not([data-theme="light"]) .highlight .cs { color: #E50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body:not([data-theme="light"]) .highlight .gd { color: #FF3A3A } /* Generic.Deleted */ +body:not([data-theme="light"]) .highlight .ge { color: #D0D0D0; font-style: italic } /* Generic.Emph */ +body:not([data-theme="light"]) .highlight .ges { color: #D0D0D0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body:not([data-theme="light"]) .highlight .gr { color: #FF3A3A } /* Generic.Error */ +body:not([data-theme="light"]) .highlight .gh { color: #FFF; font-weight: bold } /* Generic.Heading */ +body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */ +body:not([data-theme="light"]) .highlight .go { color: #CCC } /* Generic.Output */ +body:not([data-theme="light"]) .highlight .gp { color: #AAA } /* Generic.Prompt */ +body:not([data-theme="light"]) .highlight .gs { color: #D0D0D0; font-weight: bold } /* Generic.Strong */ +body:not([data-theme="light"]) .highlight .gu { color: #FFF; text-decoration: underline } /* Generic.Subheading */ +body:not([data-theme="light"]) .highlight .gt { color: #FF3A3A } /* Generic.Traceback */ +body:not([data-theme="light"]) .highlight .kc { color: #6EBF26; font-weight: bold } /* Keyword.Constant */ +body:not([data-theme="light"]) .highlight .kd { color: #6EBF26; font-weight: bold } /* Keyword.Declaration */ +body:not([data-theme="light"]) .highlight .kn { color: #6EBF26; font-weight: bold } /* Keyword.Namespace */ +body:not([data-theme="light"]) .highlight .kp { color: #6EBF26 } /* Keyword.Pseudo */ +body:not([data-theme="light"]) .highlight .kr { color: #6EBF26; font-weight: bold } /* Keyword.Reserved */ +body:not([data-theme="light"]) .highlight .kt { color: #6EBF26; font-weight: bold } /* Keyword.Type */ +body:not([data-theme="light"]) .highlight .ld { color: #D0D0D0 } /* Literal.Date */ +body:not([data-theme="light"]) .highlight .m { color: #51B2FD } /* Literal.Number */ +body:not([data-theme="light"]) .highlight .s { color: #ED9D13 } /* Literal.String */ +body:not([data-theme="light"]) .highlight .na { color: #BBB } /* Name.Attribute */ +body:not([data-theme="light"]) .highlight .nb { color: #2FBCCD } /* Name.Builtin */ +body:not([data-theme="light"]) .highlight .nc { color: #71ADFF; text-decoration: underline } /* Name.Class */ +body:not([data-theme="light"]) .highlight .no { color: #40FFFF } /* Name.Constant */ +body:not([data-theme="light"]) .highlight .nd { color: #FFA500 } /* Name.Decorator */ +body:not([data-theme="light"]) .highlight .ni { color: #D0D0D0 } /* Name.Entity */ +body:not([data-theme="light"]) .highlight .ne { color: #BBB } /* Name.Exception */ +body:not([data-theme="light"]) .highlight .nf { color: #71ADFF } /* Name.Function */ +body:not([data-theme="light"]) .highlight .nl { color: #D0D0D0 } /* Name.Label */ +body:not([data-theme="light"]) .highlight .nn { color: #71ADFF; text-decoration: underline } /* Name.Namespace */ +body:not([data-theme="light"]) .highlight .nx { color: #D0D0D0 } /* Name.Other */ +body:not([data-theme="light"]) .highlight .py { color: #D0D0D0 } /* Name.Property */ +body:not([data-theme="light"]) .highlight .nt { color: #6EBF26; font-weight: bold } /* Name.Tag */ +body:not([data-theme="light"]) .highlight .nv { color: #40FFFF } /* Name.Variable */ +body:not([data-theme="light"]) .highlight .ow { color: #6EBF26; font-weight: bold } /* Operator.Word */ +body:not([data-theme="light"]) .highlight .pm { color: #D0D0D0 } /* Punctuation.Marker */ +body:not([data-theme="light"]) .highlight .w { color: #666 } /* Text.Whitespace */ +body:not([data-theme="light"]) .highlight .mb { color: #51B2FD } /* Literal.Number.Bin */ +body:not([data-theme="light"]) .highlight .mf { color: #51B2FD } /* Literal.Number.Float */ +body:not([data-theme="light"]) .highlight .mh { color: #51B2FD } /* Literal.Number.Hex */ +body:not([data-theme="light"]) .highlight .mi { color: #51B2FD } /* Literal.Number.Integer */ +body:not([data-theme="light"]) .highlight .mo { color: #51B2FD } /* Literal.Number.Oct */ +body:not([data-theme="light"]) .highlight .sa { color: #ED9D13 } /* Literal.String.Affix */ +body:not([data-theme="light"]) .highlight .sb { color: #ED9D13 } /* Literal.String.Backtick */ +body:not([data-theme="light"]) .highlight .sc { color: #ED9D13 } /* Literal.String.Char */ +body:not([data-theme="light"]) .highlight .dl { color: #ED9D13 } /* Literal.String.Delimiter */ +body:not([data-theme="light"]) .highlight .sd { color: #ED9D13 } /* Literal.String.Doc */ +body:not([data-theme="light"]) .highlight .s2 { color: #ED9D13 } /* Literal.String.Double */ +body:not([data-theme="light"]) .highlight .se { color: #ED9D13 } /* Literal.String.Escape */ +body:not([data-theme="light"]) .highlight .sh { color: #ED9D13 } /* Literal.String.Heredoc */ +body:not([data-theme="light"]) .highlight .si { color: #ED9D13 } /* Literal.String.Interpol */ +body:not([data-theme="light"]) .highlight .sx { color: #FFA500 } /* Literal.String.Other */ +body:not([data-theme="light"]) .highlight .sr { color: #ED9D13 } /* Literal.String.Regex */ +body:not([data-theme="light"]) .highlight .s1 { color: #ED9D13 } /* Literal.String.Single */ +body:not([data-theme="light"]) .highlight .ss { color: #ED9D13 } /* Literal.String.Symbol */ +body:not([data-theme="light"]) .highlight .bp { color: #2FBCCD } /* Name.Builtin.Pseudo */ +body:not([data-theme="light"]) .highlight .fm { color: #71ADFF } /* Name.Function.Magic */ +body:not([data-theme="light"]) .highlight .vc { color: #40FFFF } /* Name.Variable.Class */ +body:not([data-theme="light"]) .highlight .vg { color: #40FFFF } /* Name.Variable.Global */ +body:not([data-theme="light"]) .highlight .vi { color: #40FFFF } /* Name.Variable.Instance */ +body:not([data-theme="light"]) .highlight .vm { color: #40FFFF } /* Name.Variable.Magic */ +body:not([data-theme="light"]) .highlight .il { color: #51B2FD } /* Literal.Number.Integer.Long */ +} +} \ No newline at end of file diff --git a/docs/build/_static/scripts/furo-extensions.js b/docs/build/_static/scripts/furo-extensions.js new file mode 100644 index 000000000..e69de29bb diff --git a/docs/build/_static/scripts/furo.js b/docs/build/_static/scripts/furo.js new file mode 100644 index 000000000..0abb2afac --- /dev/null +++ b/docs/build/_static/scripts/furo.js @@ -0,0 +1,3 @@ +/*! For license information please see furo.js.LICENSE.txt */ +(()=>{var t={856:function(t,e,n){var o,r;r=void 0!==n.g?n.g:"undefined"!=typeof window?window:this,o=function(){return function(t){"use strict";var e={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},n=function(t,e,n){if(n.settings.events){var o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e.dispatchEvent(o)}},o=function(t){var e=0;if(t.offsetParent)for(;t;)e+=t.offsetTop,t=t.offsetParent;return e>=0?e:0},r=function(t){t&&t.sort((function(t,e){return o(t.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},l=function(t,e){var n=t[t.length-1];if(function(t,e){return!(!s()||!c(t.content,e,!0))}(n,e))return n;for(var o=t.length-1;o>=0;o--)if(c(t[o].content,e))return t[o]},a=function(t,e){if(e.nested&&t.parentNode){var n=t.parentNode.closest("li");n&&(n.classList.remove(e.nestedClass),a(n,e))}},i=function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.remove(e.navClass),t.content.classList.remove(e.contentClass),a(o,e),n("gumshoeDeactivate",o,{link:t.nav,content:t.content,settings:e}))}},u=function(t,e){if(e.nested){var n=t.parentNode.closest("li");n&&(n.classList.add(e.nestedClass),u(n,e))}};return function(o,c){var s,a,d,f,m,v={setup:function(){s=document.querySelectorAll(o),a=[],Array.prototype.forEach.call(s,(function(t){var e=document.getElementById(decodeURIComponent(t.hash.substr(1)));e&&a.push({nav:t,content:e})})),r(a)},detect:function(){var t=l(a,m);t?d&&t.content===d.content||(i(d,m),function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.add(e.navClass),t.content.classList.add(e.contentClass),u(o,e),n("gumshoeActivate",o,{link:t.nav,content:t.content,settings:e}))}}(t,m),d=t):d&&(i(d,m),d=null)}},h=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame(v.detect)},g=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame((function(){r(a),v.detect()}))};return v.destroy=function(){d&&i(d,m),t.removeEventListener("scroll",h,!1),m.reflow&&t.removeEventListener("resize",g,!1),a=null,s=null,d=null,f=null,m=null},m=function(){var t={};return Array.prototype.forEach.call(arguments,(function(e){for(var n in e){if(!e.hasOwnProperty(n))return;t[n]=e[n]}})),t}(e,c||{}),v.setup(),v.detect(),t.addEventListener("scroll",h,!1),m.reflow&&t.addEventListener("resize",g,!1),v}}(r)}.apply(e,[]),void 0===o||(t.exports=o)}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=n(856),e=n.n(t),o=null,r=null,c=document.documentElement.scrollTop;const s=64;function l(){const t=localStorage.getItem("theme")||"auto";var e;"light"!==(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"auto"===t?"light":"light"==t?"dark":"auto":"auto"===t?"dark":"dark"==t?"light":"auto")&&"dark"!==e&&"auto"!==e&&(console.error(`Got invalid theme mode: ${e}. Resetting to auto.`),e="auto"),document.body.dataset.theme=e,localStorage.setItem("theme",e),console.log(`Changed to ${e} mode.`)}function a(){!function(){const t=document.getElementsByClassName("theme-toggle");Array.from(t).forEach((t=>{t.addEventListener("click",l)}))}(),function(){let t=0,e=!1;window.addEventListener("scroll",(function(n){t=window.scrollY,e||(window.requestAnimationFrame((function(){var n;(function(t){const e=Math.floor(r.getBoundingClientRect().top);console.log(`headerTop: ${e}`),0==e&&t!=e?r.classList.add("scrolled"):r.classList.remove("scrolled")})(n=t),function(t){tc&&document.documentElement.classList.remove("show-back-to-top"),c=t}(n),function(t){null!==o&&(0==t?o.scrollTo(0,0):Math.ceil(t)>=Math.floor(document.documentElement.scrollHeight-window.innerHeight)?o.scrollTo(0,o.scrollHeight):document.querySelector(".scroll-current"))}(n),e=!1})),e=!0)})),window.scroll()}(),null!==o&&new(e())(".toc-tree a",{reflow:!0,recursive:!0,navClass:"scroll-current",offset:()=>{let t=parseFloat(getComputedStyle(document.documentElement).fontSize);return r.getBoundingClientRect().height+2.5*t+1}})}document.addEventListener("DOMContentLoaded",(function(){document.body.parentNode.classList.remove("no-js"),r=document.querySelector("header"),o=document.querySelector(".toc-scroll"),a()}))})()})(); +//# sourceMappingURL=furo.js.map \ No newline at end of file diff --git a/docs/build/_static/scripts/furo.js.LICENSE.txt b/docs/build/_static/scripts/furo.js.LICENSE.txt new file mode 100644 index 000000000..1632189c7 --- /dev/null +++ b/docs/build/_static/scripts/furo.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! + * gumshoejs v5.1.2 (patched by @pradyunsg) + * A simple, framework-agnostic scrollspy script. + * (c) 2019 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/gumshoe + */ diff --git a/docs/build/_static/scripts/furo.js.map b/docs/build/_static/scripts/furo.js.map new file mode 100644 index 000000000..80ea12b85 --- /dev/null +++ b/docs/build/_static/scripts/furo.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/furo.js","mappings":"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","sources":["webpack:///./src/furo/assets/scripts/gumshoe-patched.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./src/furo/assets/scripts/furo.js"],"sourcesContent":["/*!\n * gumshoejs v5.1.2 (patched by @pradyunsg)\n * A simple, framework-agnostic scrollspy script.\n * (c) 2019 Chris Ferdinandi\n * MIT License\n * http://github.com/cferdinandi/gumshoe\n */\n\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], function () {\n return factory(root);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(root);\n } else {\n root.Gumshoe = factory(root);\n }\n})(\n typeof global !== \"undefined\"\n ? global\n : typeof window !== \"undefined\"\n ? window\n : this,\n function (window) {\n \"use strict\";\n\n //\n // Defaults\n //\n\n var defaults = {\n // Active classes\n navClass: \"active\",\n contentClass: \"active\",\n\n // Nested navigation\n nested: false,\n nestedClass: \"active\",\n\n // Offset & reflow\n offset: 0,\n reflow: false,\n\n // Event support\n events: true,\n };\n\n //\n // Methods\n //\n\n /**\n * Merge two or more objects together.\n * @param {Object} objects The objects to merge together\n * @returns {Object} Merged values of defaults and options\n */\n var extend = function () {\n var merged = {};\n Array.prototype.forEach.call(arguments, function (obj) {\n for (var key in obj) {\n if (!obj.hasOwnProperty(key)) return;\n merged[key] = obj[key];\n }\n });\n return merged;\n };\n\n /**\n * Emit a custom event\n * @param {String} type The event type\n * @param {Node} elem The element to attach the event to\n * @param {Object} detail Any details to pass along with the event\n */\n var emitEvent = function (type, elem, detail) {\n // Make sure events are enabled\n if (!detail.settings.events) return;\n\n // Create a new event\n var event = new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n detail: detail,\n });\n\n // Dispatch the event\n elem.dispatchEvent(event);\n };\n\n /**\n * Get an element's distance from the top of the Document.\n * @param {Node} elem The element\n * @return {Number} Distance from the top in pixels\n */\n var getOffsetTop = function (elem) {\n var location = 0;\n if (elem.offsetParent) {\n while (elem) {\n location += elem.offsetTop;\n elem = elem.offsetParent;\n }\n }\n return location >= 0 ? location : 0;\n };\n\n /**\n * Sort content from first to last in the DOM\n * @param {Array} contents The content areas\n */\n var sortContents = function (contents) {\n if (contents) {\n contents.sort(function (item1, item2) {\n var offset1 = getOffsetTop(item1.content);\n var offset2 = getOffsetTop(item2.content);\n if (offset1 < offset2) return -1;\n return 1;\n });\n }\n };\n\n /**\n * Get the offset to use for calculating position\n * @param {Object} settings The settings for this instantiation\n * @return {Float} The number of pixels to offset the calculations\n */\n var getOffset = function (settings) {\n // if the offset is a function run it\n if (typeof settings.offset === \"function\") {\n return parseFloat(settings.offset());\n }\n\n // Otherwise, return it as-is\n return parseFloat(settings.offset);\n };\n\n /**\n * Get the document element's height\n * @private\n * @returns {Number}\n */\n var getDocumentHeight = function () {\n return Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.offsetHeight,\n document.body.clientHeight,\n document.documentElement.clientHeight,\n );\n };\n\n /**\n * Determine if an element is in view\n * @param {Node} elem The element\n * @param {Object} settings The settings for this instantiation\n * @param {Boolean} bottom If true, check if element is above bottom of viewport instead\n * @return {Boolean} Returns true if element is in the viewport\n */\n var isInView = function (elem, settings, bottom) {\n var bounds = elem.getBoundingClientRect();\n var offset = getOffset(settings);\n if (bottom) {\n return (\n parseInt(bounds.bottom, 10) <\n (window.innerHeight || document.documentElement.clientHeight)\n );\n }\n return parseInt(bounds.top, 10) <= offset;\n };\n\n /**\n * Check if at the bottom of the viewport\n * @return {Boolean} If true, page is at the bottom of the viewport\n */\n var isAtBottom = function () {\n if (\n Math.ceil(window.innerHeight + window.pageYOffset) >=\n getDocumentHeight()\n )\n return true;\n return false;\n };\n\n /**\n * Check if the last item should be used (even if not at the top of the page)\n * @param {Object} item The last item\n * @param {Object} settings The settings for this instantiation\n * @return {Boolean} If true, use the last item\n */\n var useLastItem = function (item, settings) {\n if (isAtBottom() && isInView(item.content, settings, true)) return true;\n return false;\n };\n\n /**\n * Get the active content\n * @param {Array} contents The content areas\n * @param {Object} settings The settings for this instantiation\n * @return {Object} The content area and matching navigation link\n */\n var getActive = function (contents, settings) {\n var last = contents[contents.length - 1];\n if (useLastItem(last, settings)) return last;\n for (var i = contents.length - 1; i >= 0; i--) {\n if (isInView(contents[i].content, settings)) return contents[i];\n }\n };\n\n /**\n * Deactivate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var deactivateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested || !nav.parentNode) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Remove the active class\n li.classList.remove(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n deactivateNested(li, settings);\n };\n\n /**\n * Deactivate a nav and content area\n * @param {Object} items The nav item and content to deactivate\n * @param {Object} settings The settings for this instantiation\n */\n var deactivate = function (items, settings) {\n // Make sure there are items to deactivate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Remove the active class from the nav and content\n li.classList.remove(settings.navClass);\n items.content.classList.remove(settings.contentClass);\n\n // Deactivate any parent navs in a nested navigation\n deactivateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeDeactivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Activate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var activateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Add the active class\n li.classList.add(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n activateNested(li, settings);\n };\n\n /**\n * Activate a nav and content area\n * @param {Object} items The nav item and content to activate\n * @param {Object} settings The settings for this instantiation\n */\n var activate = function (items, settings) {\n // Make sure there are items to activate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Add the active class to the nav and content\n li.classList.add(settings.navClass);\n items.content.classList.add(settings.contentClass);\n\n // Activate any parent navs in a nested navigation\n activateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeActivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Create the Constructor object\n * @param {String} selector The selector to use for navigation items\n * @param {Object} options User options and settings\n */\n var Constructor = function (selector, options) {\n //\n // Variables\n //\n\n var publicAPIs = {};\n var navItems, contents, current, timeout, settings;\n\n //\n // Methods\n //\n\n /**\n * Set variables from DOM elements\n */\n publicAPIs.setup = function () {\n // Get all nav items\n navItems = document.querySelectorAll(selector);\n\n // Create contents array\n contents = [];\n\n // Loop through each item, get it's matching content, and push to the array\n Array.prototype.forEach.call(navItems, function (item) {\n // Get the content for the nav item\n var content = document.getElementById(\n decodeURIComponent(item.hash.substr(1)),\n );\n if (!content) return;\n\n // Push to the contents array\n contents.push({\n nav: item,\n content: content,\n });\n });\n\n // Sort contents by the order they appear in the DOM\n sortContents(contents);\n };\n\n /**\n * Detect which content is currently active\n */\n publicAPIs.detect = function () {\n // Get the active content\n var active = getActive(contents, settings);\n\n // if there's no active content, deactivate and bail\n if (!active) {\n if (current) {\n deactivate(current, settings);\n current = null;\n }\n return;\n }\n\n // If the active content is the one currently active, do nothing\n if (current && active.content === current.content) return;\n\n // Deactivate the current content and activate the new content\n deactivate(current, settings);\n activate(active, settings);\n\n // Update the currently active content\n current = active;\n };\n\n /**\n * Detect the active content on scroll\n * Debounced for performance\n */\n var scrollHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(publicAPIs.detect);\n };\n\n /**\n * Update content sorting on resize\n * Debounced for performance\n */\n var resizeHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(function () {\n sortContents(contents);\n publicAPIs.detect();\n });\n };\n\n /**\n * Destroy the current instantiation\n */\n publicAPIs.destroy = function () {\n // Undo DOM changes\n if (current) {\n deactivate(current, settings);\n }\n\n // Remove event listeners\n window.removeEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.removeEventListener(\"resize\", resizeHandler, false);\n }\n\n // Reset variables\n contents = null;\n navItems = null;\n current = null;\n timeout = null;\n settings = null;\n };\n\n /**\n * Initialize the current instantiation\n */\n var init = function () {\n // Merge user options into defaults\n settings = extend(defaults, options || {});\n\n // Setup variables based on the current DOM\n publicAPIs.setup();\n\n // Find the currently active content\n publicAPIs.detect();\n\n // Setup event listeners\n window.addEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.addEventListener(\"resize\", resizeHandler, false);\n }\n };\n\n //\n // Initialize and return the public APIs\n //\n\n init();\n return publicAPIs;\n };\n\n //\n // Return the Constructor\n //\n\n return Constructor;\n },\n);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import Gumshoe from \"./gumshoe-patched.js\";\n\n////////////////////////////////////////////////////////////////////////////////\n// Scroll Handling\n////////////////////////////////////////////////////////////////////////////////\nvar tocScroll = null;\nvar header = null;\nvar lastScrollTop = document.documentElement.scrollTop;\nconst GO_TO_TOP_OFFSET = 64;\n\nfunction scrollHandlerForHeader(positionY) {\n const headerTop = Math.floor(header.getBoundingClientRect().top);\n\n console.log(`headerTop: ${headerTop}`);\n if (headerTop == 0 && positionY != headerTop) {\n header.classList.add(\"scrolled\");\n } else {\n header.classList.remove(\"scrolled\");\n }\n}\n\nfunction scrollHandlerForBackToTop(positionY) {\n if (positionY < GO_TO_TOP_OFFSET) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n } else {\n if (positionY < lastScrollTop) {\n document.documentElement.classList.add(\"show-back-to-top\");\n } else if (positionY > lastScrollTop) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n }\n }\n lastScrollTop = positionY;\n}\n\nfunction scrollHandlerForTOC(positionY) {\n if (tocScroll === null) {\n return;\n }\n\n // top of page.\n if (positionY == 0) {\n tocScroll.scrollTo(0, 0);\n } else if (\n // bottom of page.\n Math.ceil(positionY) >=\n Math.floor(document.documentElement.scrollHeight - window.innerHeight)\n ) {\n tocScroll.scrollTo(0, tocScroll.scrollHeight);\n } else {\n // somewhere in the middle.\n const current = document.querySelector(\".scroll-current\");\n if (current == null) {\n return;\n }\n\n // https://github.com/pypa/pip/issues/9159 This breaks scroll behaviours.\n // // scroll the currently \"active\" heading in toc, into view.\n // const rect = current.getBoundingClientRect();\n // if (0 > rect.top) {\n // current.scrollIntoView(true); // the argument is \"alignTop\"\n // } else if (rect.bottom > window.innerHeight) {\n // current.scrollIntoView(false);\n // }\n }\n}\n\nfunction scrollHandler(positionY) {\n scrollHandlerForHeader(positionY);\n scrollHandlerForBackToTop(positionY);\n scrollHandlerForTOC(positionY);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Theme Toggle\n////////////////////////////////////////////////////////////////////////////////\nfunction setTheme(mode) {\n if (mode !== \"light\" && mode !== \"dark\" && mode !== \"auto\") {\n console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);\n mode = \"auto\";\n }\n\n document.body.dataset.theme = mode;\n localStorage.setItem(\"theme\", mode);\n console.log(`Changed to ${mode} mode.`);\n}\n\nfunction cycleThemeOnce() {\n const currentTheme = localStorage.getItem(\"theme\") || \"auto\";\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\n if (prefersDark) {\n // Auto (dark) -> Light -> Dark\n if (currentTheme === \"auto\") {\n setTheme(\"light\");\n } else if (currentTheme == \"light\") {\n setTheme(\"dark\");\n } else {\n setTheme(\"auto\");\n }\n } else {\n // Auto (light) -> Dark -> Light\n if (currentTheme === \"auto\") {\n setTheme(\"dark\");\n } else if (currentTheme == \"dark\") {\n setTheme(\"light\");\n } else {\n setTheme(\"auto\");\n }\n }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Setup\n////////////////////////////////////////////////////////////////////////////////\nfunction setupScrollHandler() {\n // Taken from https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event\n let last_known_scroll_position = 0;\n let ticking = false;\n\n window.addEventListener(\"scroll\", function (e) {\n last_known_scroll_position = window.scrollY;\n\n if (!ticking) {\n window.requestAnimationFrame(function () {\n scrollHandler(last_known_scroll_position);\n ticking = false;\n });\n\n ticking = true;\n }\n });\n window.scroll();\n}\n\nfunction setupScrollSpy() {\n if (tocScroll === null) {\n return;\n }\n\n // Scrollspy -- highlight table on contents, based on scroll\n new Gumshoe(\".toc-tree a\", {\n reflow: true,\n recursive: true,\n navClass: \"scroll-current\",\n offset: () => {\n let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return header.getBoundingClientRect().height + 2.5 * rem + 1;\n },\n });\n}\n\nfunction setupTheme() {\n // Attach event handlers for toggling themes\n const buttons = document.getElementsByClassName(\"theme-toggle\");\n Array.from(buttons).forEach((btn) => {\n btn.addEventListener(\"click\", cycleThemeOnce);\n });\n}\n\nfunction setup() {\n setupTheme();\n setupScrollHandler();\n setupScrollSpy();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Main entrypoint\n////////////////////////////////////////////////////////////////////////////////\nfunction main() {\n document.body.parentNode.classList.remove(\"no-js\");\n\n header = document.querySelector(\"header\");\n tocScroll = document.querySelector(\".toc-scroll\");\n\n setup();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", main);\n"],"names":["root","g","window","this","defaults","navClass","contentClass","nested","nestedClass","offset","reflow","events","emitEvent","type","elem","detail","settings","event","CustomEvent","bubbles","cancelable","dispatchEvent","getOffsetTop","location","offsetParent","offsetTop","sortContents","contents","sort","item1","item2","content","isInView","bottom","bounds","getBoundingClientRect","parseFloat","getOffset","parseInt","innerHeight","document","documentElement","clientHeight","top","isAtBottom","Math","ceil","pageYOffset","max","body","scrollHeight","offsetHeight","getActive","last","length","item","useLastItem","i","deactivateNested","nav","parentNode","li","closest","classList","remove","deactivate","items","link","activateNested","add","selector","options","navItems","current","timeout","publicAPIs","querySelectorAll","Array","prototype","forEach","call","getElementById","decodeURIComponent","hash","substr","push","active","activate","scrollHandler","cancelAnimationFrame","requestAnimationFrame","detect","resizeHandler","destroy","removeEventListener","merged","arguments","obj","key","hasOwnProperty","extend","setup","addEventListener","factory","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","n","getter","__esModule","d","a","definition","o","Object","defineProperty","enumerable","get","globalThis","Function","e","prop","tocScroll","header","lastScrollTop","scrollTop","GO_TO_TOP_OFFSET","cycleThemeOnce","currentTheme","localStorage","getItem","mode","matchMedia","matches","console","error","dataset","theme","setItem","log","buttons","getElementsByClassName","from","btn","setupTheme","last_known_scroll_position","ticking","scrollY","positionY","headerTop","floor","scrollHandlerForHeader","scrollHandlerForBackToTop","scrollTo","querySelector","scrollHandlerForTOC","scroll","setupScrollHandler","recursive","rem","getComputedStyle","fontSize","height"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/build/_static/searchtools.js b/docs/build/_static/searchtools.js new file mode 100644 index 000000000..92da3f8b2 --- /dev/null +++ b/docs/build/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlinks", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/docs/build/_static/skeleton.css b/docs/build/_static/skeleton.css new file mode 100644 index 000000000..467c878c6 --- /dev/null +++ b/docs/build/_static/skeleton.css @@ -0,0 +1,296 @@ +/* Some sane resets. */ +html { + height: 100%; +} + +body { + margin: 0; + min-height: 100%; +} + +/* All the flexbox magic! */ +body, +.sb-announcement, +.sb-content, +.sb-main, +.sb-container, +.sb-container__inner, +.sb-article-container, +.sb-footer-content, +.sb-header, +.sb-header-secondary, +.sb-footer { + display: flex; +} + +/* These order things vertically */ +body, +.sb-main, +.sb-article-container { + flex-direction: column; +} + +/* Put elements in the center */ +.sb-header, +.sb-header-secondary, +.sb-container, +.sb-content, +.sb-footer, +.sb-footer-content { + justify-content: center; +} +/* Put elements at the ends */ +.sb-article-container { + justify-content: space-between; +} + +/* These elements grow. */ +.sb-main, +.sb-content, +.sb-container, +article { + flex-grow: 1; +} + +/* Because padding making this wider is not fun */ +article { + box-sizing: border-box; +} + +/* The announcements element should never be wider than the page. */ +.sb-announcement { + max-width: 100%; +} + +.sb-sidebar-primary, +.sb-sidebar-secondary { + flex-shrink: 0; + width: 17rem; +} + +.sb-announcement__inner { + justify-content: center; + + box-sizing: border-box; + height: 3rem; + + overflow-x: auto; + white-space: nowrap; +} + +/* Sidebars, with checkbox-based toggle */ +.sb-sidebar-primary, +.sb-sidebar-secondary { + position: fixed; + height: 100%; + top: 0; +} + +.sb-sidebar-primary { + left: -17rem; + transition: left 250ms ease-in-out; +} +.sb-sidebar-secondary { + right: -17rem; + transition: right 250ms ease-in-out; +} + +.sb-sidebar-toggle { + display: none; +} +.sb-sidebar-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + + transition: width 0ms ease 250ms, height 0ms ease 250ms, opacity 250ms ease; + + opacity: 0; + background-color: rgba(0, 0, 0, 0.54); +} + +#sb-sidebar-toggle--primary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--primary"], +#sb-sidebar-toggle--secondary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--secondary"] { + width: 100%; + height: 100%; + opacity: 1; + transition: width 0ms ease, height 0ms ease, opacity 250ms ease; +} + +#sb-sidebar-toggle--primary:checked ~ .sb-container .sb-sidebar-primary { + left: 0; +} +#sb-sidebar-toggle--secondary:checked ~ .sb-container .sb-sidebar-secondary { + right: 0; +} + +/* Full-width mode */ +.drop-secondary-sidebar-for-full-width-content + .hide-when-secondary-sidebar-shown { + display: none !important; +} +.drop-secondary-sidebar-for-full-width-content .sb-sidebar-secondary { + display: none !important; +} + +/* Mobile views */ +.sb-page-width { + width: 100%; +} + +.sb-article-container, +.sb-footer-content__inner, +.drop-secondary-sidebar-for-full-width-content .sb-article, +.drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 100vw; +} + +.sb-article, +.match-content-width { + padding: 0 1rem; + box-sizing: border-box; +} + +@media (min-width: 32rem) { + .sb-article, + .match-content-width { + padding: 0 2rem; + } +} + +/* Tablet views */ +@media (min-width: 42rem) { + .sb-article-container { + width: auto; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 42rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 46rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 46rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 50rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 50rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Tablet views */ +@media (min-width: 59rem) { + .sb-sidebar-secondary { + position: static; + } + .hide-when-secondary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 63rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 67rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Desktop views */ +@media (min-width: 76rem) { + .sb-sidebar-primary { + position: static; + } + .hide-when-primary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} + +/* Full desktop views */ +@media (min-width: 80rem) { + .sb-article, + .match-content-width { + width: 46rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } +} + +@media (min-width: 84rem) { + .sb-article, + .match-content-width { + width: 50rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } +} + +@media (min-width: 88rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-page-width { + width: 88rem; + } +} diff --git a/docs/build/_static/sphinx_highlight.js b/docs/build/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/docs/build/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/docs/build/_static/styles/furo-extensions.css b/docs/build/_static/styles/furo-extensions.css new file mode 100644 index 000000000..822958761 --- /dev/null +++ b/docs/build/_static/styles/furo-extensions.css @@ -0,0 +1,2 @@ +#furo-sidebar-ad-placement{padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)}#furo-sidebar-ad-placement .ethical-sidebar{background:var(--color-background-secondary);border:none;box-shadow:none}#furo-sidebar-ad-placement .ethical-sidebar:hover{background:var(--color-background-hover)}#furo-sidebar-ad-placement .ethical-sidebar a{color:var(--color-foreground-primary)}#furo-sidebar-ad-placement .ethical-callout a{color:var(--color-foreground-secondary)!important}#furo-readthedocs-versions{background:transparent;display:block;position:static;width:100%}#furo-readthedocs-versions .rst-versions{background:#1a1c1e}#furo-readthedocs-versions .rst-current-version{background:var(--color-sidebar-item-background);cursor:unset}#furo-readthedocs-versions .rst-current-version:hover{background:var(--color-sidebar-item-background)}#furo-readthedocs-versions .rst-current-version .fa-book{color:var(--color-foreground-primary)}#furo-readthedocs-versions>.rst-other-versions{padding:0}#furo-readthedocs-versions>.rst-other-versions small{opacity:1}#furo-readthedocs-versions .injected .rst-versions{position:unset}#furo-readthedocs-versions:focus-within,#furo-readthedocs-versions:hover{box-shadow:0 0 0 1px var(--color-sidebar-background-border)}#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:hover .rst-current-version{background:#1a1c1e;font-size:inherit;height:auto;line-height:inherit;padding:12px;text-align:right}#furo-readthedocs-versions:focus-within .rst-current-version .fa-book,#furo-readthedocs-versions:hover .rst-current-version .fa-book{color:#fff;float:left}#furo-readthedocs-versions:focus-within .fa-caret-down,#furo-readthedocs-versions:hover .fa-caret-down{display:none}#furo-readthedocs-versions:focus-within .injected,#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:focus-within .rst-other-versions,#furo-readthedocs-versions:hover .injected,#furo-readthedocs-versions:hover .rst-current-version,#furo-readthedocs-versions:hover .rst-other-versions{display:block}#furo-readthedocs-versions:focus-within>.rst-current-version,#furo-readthedocs-versions:hover>.rst-current-version{display:none}.highlight:hover button.copybtn{color:var(--color-code-foreground)}.highlight button.copybtn{align-items:center;background-color:var(--color-code-background);border:none;color:var(--color-background-item);cursor:pointer;height:1.25em;right:.5rem;top:.625rem;transition:color .3s,opacity .3s;width:1.25em}.highlight button.copybtn:hover{background-color:var(--color-code-background);color:var(--color-brand-content)}.highlight button.copybtn:after{background-color:transparent;color:var(--color-code-foreground);display:none}.highlight button.copybtn.success{color:#22863a;transition:color 0ms}.highlight button.copybtn.success:after{display:block}.highlight button.copybtn svg{padding:0}body{--sd-color-primary:var(--color-brand-primary);--sd-color-primary-highlight:var(--color-brand-content);--sd-color-primary-text:var(--color-background-primary);--sd-color-shadow:rgba(0,0,0,.05);--sd-color-card-border:var(--color-card-border);--sd-color-card-border-hover:var(--color-brand-content);--sd-color-card-background:var(--color-card-background);--sd-color-card-text:var(--color-foreground-primary);--sd-color-card-header:var(--color-card-marginals-background);--sd-color-card-footer:var(--color-card-marginals-background);--sd-color-tabs-label-active:var(--color-brand-content);--sd-color-tabs-label-hover:var(--color-foreground-muted);--sd-color-tabs-label-inactive:var(--color-foreground-muted);--sd-color-tabs-underline-active:var(--color-brand-content);--sd-color-tabs-underline-hover:var(--color-foreground-border);--sd-color-tabs-underline-inactive:var(--color-background-border);--sd-color-tabs-overline:var(--color-background-border);--sd-color-tabs-underline:var(--color-background-border)}.sd-tab-content{box-shadow:0 -2px var(--sd-color-tabs-overline),0 1px var(--sd-color-tabs-underline)}.sd-card{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)}.sd-shadow-sm{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-md{box-shadow:0 .3rem .75rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-lg{box-shadow:0 .6rem 1.5rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-card-hover:hover{transform:none}.sd-cards-carousel{gap:.25rem;padding:.25rem}body{--tabs--label-text:var(--color-foreground-muted);--tabs--label-text--hover:var(--color-foreground-muted);--tabs--label-text--active:var(--color-brand-content);--tabs--label-text--active--hover:var(--color-brand-content);--tabs--label-background:transparent;--tabs--label-background--hover:transparent;--tabs--label-background--active:transparent;--tabs--label-background--active--hover:transparent;--tabs--padding-x:0.25em;--tabs--margin-x:1em;--tabs--border:var(--color-background-border);--tabs--label-border:transparent;--tabs--label-border--hover:var(--color-foreground-muted);--tabs--label-border--active:var(--color-brand-content);--tabs--label-border--active--hover:var(--color-brand-content)}[role=main] .container{max-width:none;padding-left:0;padding-right:0}.shadow.docutils{border:none;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)!important}.sphinx-bs .card{background-color:var(--color-background-secondary);color:var(--color-foreground)} +/*# sourceMappingURL=furo-extensions.css.map*/ \ No newline at end of file diff --git a/docs/build/_static/styles/furo-extensions.css.map b/docs/build/_static/styles/furo-extensions.css.map new file mode 100644 index 000000000..c26eac7f5 --- /dev/null +++ b/docs/build/_static/styles/furo-extensions.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo-extensions.css","mappings":"AAGA,2BACE,oFACA,4CAKE,6CAHA,YACA,eAEA,CACA,kDACE,yCAEF,8CACE,sCAEJ,8CACE,kDAEJ,2BAGE,uBACA,cAHA,gBACA,UAEA,CAGA,yCACE,mBAEF,gDAEE,gDADA,YACA,CACA,sDACE,gDACF,yDACE,sCAEJ,+CACE,UACA,qDACE,UAGF,mDACE,eAEJ,yEAEE,4DAEA,mHASE,mBAPA,kBAEA,YADA,oBAGA,aADA,gBAIA,CAEA,qIAEE,WADA,UACA,CAEJ,uGACE,aAEF,iUAGE,cAEF,mHACE,aC1EJ,gCACE,mCAEF,0BAEE,mBAUA,8CACA,YAFA,mCAKA,eAZA,cAIA,YADA,YAYA,iCAdA,YAcA,CAEA,gCAEE,8CADA,gCACA,CAEF,gCAGE,6BADA,mCADA,YAEA,CAEF,kCAEE,cADA,oBACA,CACA,wCACE,cAEJ,8BACE,UCzCN,KAEE,6CAA8C,CAC9C,uDAAwD,CACxD,uDAAwD,CAGxD,iCAAsC,CAGtC,+CAAgD,CAChD,uDAAwD,CACxD,uDAAwD,CACxD,oDAAqD,CACrD,6DAA8D,CAC9D,6DAA8D,CAG9D,uDAAwD,CACxD,yDAA0D,CAC1D,4DAA6D,CAC7D,2DAA4D,CAC5D,8DAA+D,CAC/D,iEAAkE,CAClE,uDAAwD,CACxD,wDAAyD,CAG3D,gBACE,qFAGF,SACE,6EAEF,cACE,uFAEF,cACE,uFAEF,cACE,uFAGF,qBACE,eAEF,mBACE,WACA,eChDF,KACE,gDAAiD,CACjD,uDAAwD,CACxD,qDAAsD,CACtD,4DAA6D,CAC7D,oCAAqC,CACrC,2CAA4C,CAC5C,4CAA6C,CAC7C,mDAAoD,CACpD,wBAAyB,CACzB,oBAAqB,CACrB,6CAA8C,CAC9C,gCAAiC,CACjC,yDAA0D,CAC1D,uDAAwD,CACxD,8DAA+D,CCbjE,uBACE,eACA,eACA,gBAGF,iBACE,YACA,+EAGF,iBACE,mDACA","sources":["webpack:///./src/furo/assets/styles/extensions/_readthedocs.sass","webpack:///./src/furo/assets/styles/extensions/_copybutton.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-design.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-inline-tabs.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-panels.sass"],"sourcesContent":["// This file contains the styles used for tweaking how ReadTheDoc's embedded\n// contents would show up inside the theme.\n\n#furo-sidebar-ad-placement\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n .ethical-sidebar\n // Remove the border and box-shadow.\n border: none\n box-shadow: none\n // Manage the background colors.\n background: var(--color-background-secondary)\n &:hover\n background: var(--color-background-hover)\n // Ensure the text is legible.\n a\n color: var(--color-foreground-primary)\n\n .ethical-callout a\n color: var(--color-foreground-secondary) !important\n\n#furo-readthedocs-versions\n position: static\n width: 100%\n background: transparent\n display: block\n\n // Make the background color fit with the theme's aesthetic.\n .rst-versions\n background: rgb(26, 28, 30)\n\n .rst-current-version\n cursor: unset\n background: var(--color-sidebar-item-background)\n &:hover\n background: var(--color-sidebar-item-background)\n .fa-book\n color: var(--color-foreground-primary)\n\n > .rst-other-versions\n padding: 0\n small\n opacity: 1\n\n .injected\n .rst-versions\n position: unset\n\n &:hover,\n &:focus-within\n box-shadow: 0 0 0 1px var(--color-sidebar-background-border)\n\n .rst-current-version\n // Undo the tweaks done in RTD's CSS\n font-size: inherit\n line-height: inherit\n height: auto\n text-align: right\n padding: 12px\n\n // Match the rest of the body\n background: #1a1c1e\n\n .fa-book\n float: left\n color: white\n\n .fa-caret-down\n display: none\n\n .rst-current-version,\n .rst-other-versions,\n .injected\n display: block\n\n > .rst-current-version\n display: none\n",".highlight\n &:hover button.copybtn\n color: var(--color-code-foreground)\n\n button.copybtn\n // Align things correctly\n align-items: center\n\n height: 1.25em\n width: 1.25em\n\n top: 0.625rem // $code-spacing-vertical\n right: 0.5rem\n\n // Make it look better\n color: var(--color-background-item)\n background-color: var(--color-code-background)\n border: none\n\n // Change to cursor to make it obvious that you can click on it\n cursor: pointer\n\n // Transition smoothly, for aesthetics\n transition: color 300ms, opacity 300ms\n\n &:hover\n color: var(--color-brand-content)\n background-color: var(--color-code-background)\n\n &::after\n display: none\n color: var(--color-code-foreground)\n background-color: transparent\n\n &.success\n transition: color 0ms\n color: #22863a\n &::after\n display: block\n\n svg\n padding: 0\n","body\n // Colors\n --sd-color-primary: var(--color-brand-primary)\n --sd-color-primary-highlight: var(--color-brand-content)\n --sd-color-primary-text: var(--color-background-primary)\n\n // Shadows\n --sd-color-shadow: rgba(0, 0, 0, 0.05)\n\n // Cards\n --sd-color-card-border: var(--color-card-border)\n --sd-color-card-border-hover: var(--color-brand-content)\n --sd-color-card-background: var(--color-card-background)\n --sd-color-card-text: var(--color-foreground-primary)\n --sd-color-card-header: var(--color-card-marginals-background)\n --sd-color-card-footer: var(--color-card-marginals-background)\n\n // Tabs\n --sd-color-tabs-label-active: var(--color-brand-content)\n --sd-color-tabs-label-hover: var(--color-foreground-muted)\n --sd-color-tabs-label-inactive: var(--color-foreground-muted)\n --sd-color-tabs-underline-active: var(--color-brand-content)\n --sd-color-tabs-underline-hover: var(--color-foreground-border)\n --sd-color-tabs-underline-inactive: var(--color-background-border)\n --sd-color-tabs-overline: var(--color-background-border)\n --sd-color-tabs-underline: var(--color-background-border)\n\n// Tabs\n.sd-tab-content\n box-shadow: 0 -2px var(--sd-color-tabs-overline), 0 1px var(--sd-color-tabs-underline)\n\n// Shadows\n.sd-card // Have a shadow by default\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n.sd-shadow-sm\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-md\n box-shadow: 0 0.3rem 0.75rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-lg\n box-shadow: 0 0.6rem 1.5rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Cards\n.sd-card-hover:hover // Don't change scale on hover\n transform: none\n\n.sd-cards-carousel // Have a bit of gap in the carousel by default\n gap: 0.25rem\n padding: 0.25rem\n","// This file contains styles to tweak sphinx-inline-tabs to work well with Furo.\n\nbody\n --tabs--label-text: var(--color-foreground-muted)\n --tabs--label-text--hover: var(--color-foreground-muted)\n --tabs--label-text--active: var(--color-brand-content)\n --tabs--label-text--active--hover: var(--color-brand-content)\n --tabs--label-background: transparent\n --tabs--label-background--hover: transparent\n --tabs--label-background--active: transparent\n --tabs--label-background--active--hover: transparent\n --tabs--padding-x: 0.25em\n --tabs--margin-x: 1em\n --tabs--border: var(--color-background-border)\n --tabs--label-border: transparent\n --tabs--label-border--hover: var(--color-foreground-muted)\n --tabs--label-border--active: var(--color-brand-content)\n --tabs--label-border--active--hover: var(--color-brand-content)\n","// This file contains styles to tweak sphinx-panels to work well with Furo.\n\n// sphinx-panels includes Bootstrap 4, which uses .container which can conflict\n// with docutils' `.. container::` directive.\n[role=\"main\"] .container\n max-width: initial\n padding-left: initial\n padding-right: initial\n\n// Make the panels look nicer!\n.shadow.docutils\n border: none\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Make panel colors respond to dark mode\n.sphinx-bs .card\n background-color: var(--color-background-secondary)\n color: var(--color-foreground)\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/docs/build/_static/styles/furo.css b/docs/build/_static/styles/furo.css new file mode 100644 index 000000000..05a56b17f --- /dev/null +++ b/docs/build/_static/styles/furo.css @@ -0,0 +1,2 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,p,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;background:var(--color-background-primary);border:0!important;color:var(--color-foreground-primary);white-space:nowrap!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-stack--headings:var(--font-stack);--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8,');--icon-pencil:url('data:image/svg+xml;charset=utf-8,');--icon-abstract:url('data:image/svg+xml;charset=utf-8,');--icon-info:url('data:image/svg+xml;charset=utf-8,');--icon-flame:url('data:image/svg+xml;charset=utf-8,');--icon-question:url('data:image/svg+xml;charset=utf-8,');--icon-warning:url('data:image/svg+xml;charset=utf-8,');--icon-failure:url('data:image/svg+xml;charset=utf-8,');--icon-spark:url('data:image/svg+xml;charset=utf-8,');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#6b6f76;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#0a4bff;--color-brand-content:#2757dd;--color-brand-visited:#872ee0;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-api-added:#21632c;--color-api-added-border:#38a84d;--color-api-changed:#046172;--color-api-changed-border:#06a1bc;--color-api-deprecated:#605706;--color-api-deprecated-border:#f0d90f;--color-api-removed:#b30000;--color-api-removed-border:#ff5c5c;--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link--hover:var(--color-brand-content);--color-link-underline--hover:var(--color-foreground-border);--color-link--visited:var(--color-brand-visited);--color-link-underline--visited:var(--color-background-border);--color-link--visited--hover:var(--color-brand-visited);--color-link-underline--visited--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:block}@media(prefers-color-scheme:dark){body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-dark{display:block}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:none}}body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-family:var(--font-stack--headings);font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:visited{color:var(--color-link--visited);text-decoration-color:var(--color-link-underline--visited)}a:visited:hover{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link:hover:visited{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{height:100%}.skip-to-content,body,html{background:var(--color-background-primary);color:var(--color-foreground-primary)}.skip-to-content{border-radius:1rem;left:.25rem;padding:1rem;position:fixed;top:.25rem;transform:translateY(-200%);transition:transform .3s ease-in-out;z-index:40}.skip-to-content:focus-within{transform:translateY(0)}article{background:var(--color-content-background);color:var(--color-content-foreground);overflow-wrap:break-word}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{display:flex}.theme-toggle{background:transparent;border:none;cursor:pointer;display:flex;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1.25rem;width:1.25rem}.theme-toggle-header{align-items:center;display:flex;justify-content:center}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1.5rem;width:1.5rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg,.content-icon-container .view-this-page svg{color:inherit;height:1.25rem;width:1.25rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{height:1rem;width:1rem;fill:currentColor;display:inline-block}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.content{margin-left:auto;margin-right:auto;padding:0 1em}}@media(max-width:63em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.theme-toggle-header,.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.5rem;width:1.5rem}:target{scroll-margin-top:calc(var(--header-height) + 2.5rem)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}}@media(max-width:48em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){article[role=main] aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}.admonition p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}.admonition p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:4.25rem}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}div.deprecated,div.versionadded,div.versionchanged,div.versionremoved{border-left:.1875rem solid;border-radius:.125rem;padding-left:.75rem}div.deprecated p,div.versionadded p,div.versionchanged p,div.versionremoved p{margin-bottom:.125rem;margin-top:.125rem}div.versionadded{border-color:var(--color-api-added-border)}div.versionadded .versionmodified{color:var(--color-api-added)}div.versionchanged{border-color:var(--color-api-changed-border)}div.versionchanged .versionmodified{color:var(--color-api-changed)}div.deprecated{border-color:var(--color-api-deprecated-border)}div.deprecated .versionmodified{color:var(--color-api-deprecated)}div.versionremoved{border-color:var(--color-api-removed-border)}div.versionremoved .versionmodified{color:var(--color-api-removed)}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);padding:.1em .2em}pre.literal-block .sig-inline,pre.literal-block code.literal{font-size:inherit;padding:0}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>:not(span),div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}[role=main] .table-wrapper.container{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:2.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(2.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(2.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover);color:var(--color-sidebar-link-text)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23607D8B' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Cpath stroke='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree a.reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling. Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right} +/*# sourceMappingURL=furo.css.map*/ \ No newline at end of file diff --git a/docs/build/_static/styles/furo.css.map b/docs/build/_static/styles/furo.css.map new file mode 100644 index 000000000..3ecc37150 --- /dev/null +++ b/docs/build/_static/styles/furo.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo.css","mappings":"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sCAIA,aADF,WACE,CAKF,SACE,CAHJ,kBAEE,CAJE,gBAEJ,CAHI,iBAMA,yFAKA,aACA,eACA,cElbJ,iBAEE,aADA,iBACA,6BAEA,kCAEA,SACA,UAIA,gCACA,CALA,SAEA,SAEA,CAJA,0EAEA,CAFA,OAKA,CAGA,mDACE,iBAGF,gCACE,CADF,UACE,aAEJ,iCAEE,CAFF,UAEE,wCAEA,WACA,WADA,UACA,CACA,4CAGA,MACA,CADA,KACA,wCACA,UAGA,CAJA,UAIA,6DAUA,0CACE,CAFF,mBAEE,wEACA,CAVA,YACA,CAMF,mBAJE,OAOA,gBAJJ,gCACE,CANE,cACA,CAHA,oBACA,CAGA,QAGJ,CAII,0BACA,CADA,UACA,wCAEJ,kBACE,0DACA,gCACE,kBACA,CADA,YACA,oEACA,2CAMF,mDAII,CALN,YACE,CANE,cAKJ,CACE,iBAII,kEACA,yCACE,kDACA,yDACE,+CACA,uBANN,CAMM,+BANN,uCACE,qDACA,4BAEE,mBADA,0CACA,CADA,qBACA,0DACE,wCACA,sGALJ,oCACA,sBACE,kBAFF,UAEE,2CACA,wFACE,cACA,kEANN,uBACE,iDACA,CADA,UACA,0DACE,wDAEE,iEACA,qEANN,sCACE,CAGE,iBAHF,gBAGE,qBACE,CAJJ,uBACA,gDACE,wDACA,6DAHF,2CACA,CADA,gBACA,eACE,CAGE,sBANN,8BACE,CAII,iBAFF,4DACA,WACE,YADF,uCACE,6EACA,2BANN,8CACE,kDACA,0CACE,8BACA,yFACE,sBACA,sFALJ,mEACA,sBACE,kEACA,6EACE,uCACA,kEALJ,qGAEE,kEACA,6EACE,uCACA,kEALJ,8CACA,uDACE,sEACA,2EACE,sCACA,iEALJ,mGACA,qCACE,oDACA,0DACE,6GACA,gDAGR,yDCrEA,sEACE,CACA,6GACE,gEACF,iGAIF,wFACE,qDAGA,mGAEE,2CAEF,4FACE,gCACF,wGACE,8DAEE,6FAIA,iJAKN,6GACE,gDAKF,yDACA,qCAGA,6BACA,kBACA,qDAKA,oCAEA,+DAGA,2CAGE,oDAIA,oEAEE,qBAGJ,wDAEE,uCAEF,kE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","sources":["webpack:///./node_modules/normalize.css/normalize.css","webpack:///./src/furo/assets/styles/base/_print.sass","webpack:///./src/furo/assets/styles/base/_screen-readers.sass","webpack:///./src/furo/assets/styles/base/_theme.sass","webpack:///./src/furo/assets/styles/variables/_fonts.scss","webpack:///./src/furo/assets/styles/variables/_spacing.scss","webpack:///./src/furo/assets/styles/variables/_icons.scss","webpack:///./src/furo/assets/styles/variables/_admonitions.scss","webpack:///./src/furo/assets/styles/variables/_colors.scss","webpack:///./src/furo/assets/styles/base/_typography.sass","webpack:///./src/furo/assets/styles/_scaffold.sass","webpack:///./src/furo/assets/styles/variables/_layout.scss","webpack:///./src/furo/assets/styles/content/_admonitions.sass","webpack:///./src/furo/assets/styles/content/_api.sass","webpack:///./src/furo/assets/styles/content/_blocks.sass","webpack:///./src/furo/assets/styles/content/_captions.sass","webpack:///./src/furo/assets/styles/content/_code.sass","webpack:///./src/furo/assets/styles/content/_footnotes.sass","webpack:///./src/furo/assets/styles/content/_images.sass","webpack:///./src/furo/assets/styles/content/_indexes.sass","webpack:///./src/furo/assets/styles/content/_lists.sass","webpack:///./src/furo/assets/styles/content/_math.sass","webpack:///./src/furo/assets/styles/content/_misc.sass","webpack:///./src/furo/assets/styles/content/_rubrics.sass","webpack:///./src/furo/assets/styles/content/_sidebar.sass","webpack:///./src/furo/assets/styles/content/_tables.sass","webpack:///./src/furo/assets/styles/content/_target.sass","webpack:///./src/furo/assets/styles/content/_gui-labels.sass","webpack:///./src/furo/assets/styles/components/_footer.sass","webpack:///./src/furo/assets/styles/components/_sidebar.sass","webpack:///./src/furo/assets/styles/components/_table_of_contents.sass","webpack:///./src/furo/assets/styles/_shame.sass"],"sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","// This file contains styles for managing print media.\n\n////////////////////////////////////////////////////////////////////////////////\n// Hide elements not relevant to print media.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Hide icon container.\n .content-icon-container\n display: none !important\n\n // Hide showing header links if hovering over when printing.\n .headerlink\n display: none !important\n\n // Hide mobile header.\n .mobile-header\n display: none !important\n\n // Hide navigation links.\n .related-pages\n display: none !important\n\n////////////////////////////////////////////////////////////////////////////////\n// Tweaks related to decolorization.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Apply a border around code which no longer have a color background.\n .highlight\n border: 0.1pt solid var(--color-foreground-border)\n\n////////////////////////////////////////////////////////////////////////////////\n// Avoid page break in some relevant cases.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n ul, ol, dl, a, table, pre, blockquote, p\n page-break-inside: avoid\n\n h1, h2, h3, h4, h5, h6, img, figure, caption\n page-break-inside: avoid\n page-break-after: avoid\n\n ul, ol, dl\n page-break-before: avoid\n",".visually-hidden\n position: absolute !important\n width: 1px !important\n height: 1px !important\n padding: 0 !important\n margin: -1px !important\n overflow: hidden !important\n clip: rect(0,0,0,0) !important\n white-space: nowrap !important\n border: 0 !important\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n:-moz-focusring\n outline: auto\n","// This file serves as the \"skeleton\" of the theming logic.\n//\n// This contains the bulk of the logic for handling dark mode, color scheme\n// toggling and the handling of color-scheme-specific hiding of elements.\n\nbody\n @include fonts\n @include spacing\n @include icons\n @include admonitions\n @include default-admonition(#651fff, \"abstract\")\n @include default-topic(#14B8A6, \"pencil\")\n\n @include colors\n\n.only-light\n display: block !important\nhtml body .only-dark\n display: none !important\n\n// Ignore dark-mode hints if print media.\n@media not print\n // Enable dark-mode, if requested.\n body[data-theme=\"dark\"]\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n // Enable dark mode, unless explicitly told to avoid.\n @media (prefers-color-scheme: dark)\n body:not([data-theme=\"light\"])\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n//\n// Theme toggle presentation\n//\nbody[data-theme=\"auto\"]\n .theme-toggle svg.theme-icon-when-auto-light\n display: block\n\n @media (prefers-color-scheme: dark)\n .theme-toggle svg.theme-icon-when-auto-dark\n display: block\n .theme-toggle svg.theme-icon-when-auto-light\n display: none\n\nbody[data-theme=\"dark\"]\n .theme-toggle svg.theme-icon-when-dark\n display: block\n\nbody[data-theme=\"light\"]\n .theme-toggle svg.theme-icon-when-light\n display: block\n","// Fonts used by this theme.\n//\n// There are basically two things here -- using the system font stack and\n// defining sizes for various elements in %ages. We could have also used `em`\n// but %age is easier to reason about for me.\n\n@mixin fonts {\n // These are adapted from https://systemfontstack.com/\n --font-stack: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --font-stack--monospace: \"SFMono-Regular\", Menlo, Consolas, Monaco,\n Liberation Mono, Lucida Console, monospace;\n --font-stack--headings: var(--font-stack);\n\n --font-size--normal: 100%;\n --font-size--small: 87.5%;\n --font-size--small--2: 81.25%;\n --font-size--small--3: 75%;\n --font-size--small--4: 62.5%;\n\n // Sidebar\n --sidebar-caption-font-size: var(--font-size--small--2);\n --sidebar-item-font-size: var(--font-size--small);\n --sidebar-search-input-font-size: var(--font-size--small);\n\n // Table of Contents\n --toc-font-size: var(--font-size--small--3);\n --toc-font-size--mobile: var(--font-size--normal);\n --toc-title-font-size: var(--font-size--small--4);\n\n // Admonitions\n //\n // These aren't defined in terms of %ages, since nesting these is permitted.\n --admonition-font-size: 0.8125rem;\n --admonition-title-font-size: 0.8125rem;\n\n // Code\n --code-font-size: var(--font-size--small--2);\n\n // API\n --api-font-size: var(--font-size--small);\n}\n","// Spacing for various elements on the page\n//\n// If the user wants to tweak things in a certain way, they are permitted to.\n// They also have to deal with the consequences though!\n\n@mixin spacing {\n // Header!\n --header-height: calc(\n var(--sidebar-item-line-height) + 4 * #{var(--sidebar-item-spacing-vertical)}\n );\n --header-padding: 0.5rem;\n\n // Sidebar\n --sidebar-tree-space-above: 1.5rem;\n --sidebar-caption-space-above: 1rem;\n\n --sidebar-item-line-height: 1rem;\n --sidebar-item-spacing-vertical: 0.5rem;\n --sidebar-item-spacing-horizontal: 1rem;\n --sidebar-item-height: calc(\n var(--sidebar-item-line-height) + 2 *#{var(--sidebar-item-spacing-vertical)}\n );\n\n --sidebar-expander-width: var(--sidebar-item-height); // be square\n\n --sidebar-search-space-above: 0.5rem;\n --sidebar-search-input-spacing-vertical: 0.5rem;\n --sidebar-search-input-spacing-horizontal: 0.5rem;\n --sidebar-search-input-height: 1rem;\n --sidebar-search-icon-size: var(--sidebar-search-input-height);\n\n // Table of Contents\n --toc-title-padding: 0.25rem 0;\n --toc-spacing-vertical: 1.5rem;\n --toc-spacing-horizontal: 1.5rem;\n --toc-item-spacing-vertical: 0.4rem;\n --toc-item-spacing-horizontal: 1rem;\n}\n","// Expose theme icons as CSS variables.\n\n$icons: (\n // Adapted from tabler-icons\n // url: https://tablericons.com/\n \"search\":\n url('data:image/svg+xml;charset=utf-8,'),\n // Factored out from mkdocs-material on 24-Aug-2020.\n // url: https://squidfunk.github.io/mkdocs-material/reference/admonitions/\n \"pencil\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"abstract\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"info\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"flame\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"question\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"warning\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"failure\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"spark\":\n url('data:image/svg+xml;charset=utf-8,')\n);\n\n@mixin icons {\n @each $name, $glyph in $icons {\n --icon-#{$name}: #{$glyph};\n }\n}\n","// Admonitions\n\n// Structure of these is:\n// admonition-class: color \"icon-name\";\n//\n// The colors are translated into CSS variables below. The icons are\n// used directly in the main declarations to set the `mask-image` in\n// the title.\n\n// prettier-ignore\n$admonitions: (\n // Each of these has an reST directives for it.\n \"caution\": #ff9100 \"spark\",\n \"warning\": #ff9100 \"warning\",\n \"danger\": #ff5252 \"spark\",\n \"attention\": #ff5252 \"warning\",\n \"error\": #ff5252 \"failure\",\n \"hint\": #00c852 \"question\",\n \"tip\": #00c852 \"info\",\n \"important\": #00bfa5 \"flame\",\n \"note\": #00b0ff \"pencil\",\n \"seealso\": #448aff \"info\",\n \"admonition-todo\": #808080 \"pencil\"\n);\n\n@mixin default-admonition($color, $icon-name) {\n --color-admonition-title: #{$color};\n --color-admonition-title-background: #{rgba($color, 0.2)};\n\n --icon-admonition-default: var(--icon-#{$icon-name});\n}\n\n@mixin default-topic($color, $icon-name) {\n --color-topic-title: #{$color};\n --color-topic-title-background: #{rgba($color, 0.2)};\n\n --icon-topic-default: var(--icon-#{$icon-name});\n}\n\n@mixin admonitions {\n @each $name, $values in $admonitions {\n --color-admonition-title--#{$name}: #{nth($values, 1)};\n --color-admonition-title-background--#{$name}: #{rgba(\n nth($values, 1),\n 0.2\n )};\n }\n}\n","// Colors used throughout this theme.\n//\n// The aim is to give the user more control. Thus, instead of hard-coding colors\n// in various parts of the stylesheet, the approach taken is to define all\n// colors as CSS variables and reusing them in all the places.\n//\n// `colors-dark` depends on `colors` being included at a lower specificity.\n\n@mixin colors {\n --color-problematic: #b30000;\n\n // Base Colors\n --color-foreground-primary: black; // for main text and headings\n --color-foreground-secondary: #5a5c63; // for secondary text\n --color-foreground-muted: #6b6f76; // for muted text\n --color-foreground-border: #878787; // for content borders\n\n --color-background-primary: white; // for content\n --color-background-secondary: #f8f9fb; // for navigation + ToC\n --color-background-hover: #efeff4ff; // for navigation-item hover\n --color-background-hover--transparent: #efeff400;\n --color-background-border: #eeebee; // for UI borders\n --color-background-item: #ccc; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #0a4bff;\n --color-brand-content: #2757dd;\n --color-brand-visited: #872ee0;\n\n // API documentation\n --color-api-background: var(--color-background-hover--transparent);\n --color-api-background-hover: var(--color-background-hover);\n --color-api-overall: var(--color-foreground-secondary);\n --color-api-name: var(--color-problematic);\n --color-api-pre-name: var(--color-problematic);\n --color-api-paren: var(--color-foreground-secondary);\n --color-api-keyword: var(--color-foreground-primary);\n\n --color-api-added: #21632c;\n --color-api-added-border: #38a84d;\n --color-api-changed: #046172;\n --color-api-changed-border: #06a1bc;\n --color-api-deprecated: #605706;\n --color-api-deprecated-border: #f0d90f;\n --color-api-removed: #b30000;\n --color-api-removed-border: #ff5c5c;\n\n --color-highlight-on-target: #ffffcc;\n\n // Inline code background\n --color-inline-code-background: var(--color-background-secondary);\n\n // Highlighted text (search)\n --color-highlighted-background: #ddeeff;\n --color-highlighted-text: var(--color-foreground-primary);\n\n // GUI Labels\n --color-guilabel-background: #ddeeff80;\n --color-guilabel-border: #bedaf580;\n --color-guilabel-text: var(--color-foreground-primary);\n\n // Admonitions!\n --color-admonition-background: transparent;\n\n //////////////////////////////////////////////////////////////////////////////\n // Everything below this should be one of:\n // - var(...)\n // - *-gradient(...)\n // - special literal values (eg: transparent, none)\n //////////////////////////////////////////////////////////////////////////////\n\n // Tables\n --color-table-header-background: var(--color-background-secondary);\n --color-table-border: var(--color-background-border);\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: transparent;\n --color-card-marginals-background: var(--color-background-secondary);\n\n // Header\n --color-header-background: var(--color-background-primary);\n --color-header-border: var(--color-background-border);\n --color-header-text: var(--color-foreground-primary);\n\n // Sidebar (left)\n --color-sidebar-background: var(--color-background-secondary);\n --color-sidebar-background-border: var(--color-background-border);\n\n --color-sidebar-brand-text: var(--color-foreground-primary);\n --color-sidebar-caption-text: var(--color-foreground-muted);\n --color-sidebar-link-text: var(--color-foreground-secondary);\n --color-sidebar-link-text--top-level: var(--color-brand-primary);\n\n --color-sidebar-item-background: var(--color-sidebar-background);\n --color-sidebar-item-background--current: var(\n --color-sidebar-item-background\n );\n --color-sidebar-item-background--hover: linear-gradient(\n 90deg,\n var(--color-background-hover--transparent) 0%,\n var(--color-background-hover) var(--sidebar-item-spacing-horizontal),\n var(--color-background-hover) 100%\n );\n\n --color-sidebar-item-expander-background: transparent;\n --color-sidebar-item-expander-background--hover: var(\n --color-background-hover\n );\n\n --color-sidebar-search-text: var(--color-foreground-primary);\n --color-sidebar-search-background: var(--color-background-secondary);\n --color-sidebar-search-background--focus: var(--color-background-primary);\n --color-sidebar-search-border: var(--color-background-border);\n --color-sidebar-search-icon: var(--color-foreground-muted);\n\n // Table of Contents (right)\n --color-toc-background: var(--color-background-primary);\n --color-toc-title-text: var(--color-foreground-muted);\n --color-toc-item-text: var(--color-foreground-secondary);\n --color-toc-item-text--hover: var(--color-foreground-primary);\n --color-toc-item-text--active: var(--color-brand-primary);\n\n // Actual page contents\n --color-content-foreground: var(--color-foreground-primary);\n --color-content-background: transparent;\n\n // Links\n --color-link: var(--color-brand-content);\n --color-link-underline: var(--color-background-border);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline--hover: var(--color-foreground-border);\n\n --color-link--visited: var(--color-brand-visited);\n --color-link-underline--visited: var(--color-background-border);\n --color-link--visited--hover: var(--color-brand-visited);\n --color-link-underline--visited--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #cfd0d0; // for main text and headings\n --color-foreground-secondary: #9ca0a5; // for secondary text\n --color-foreground-muted: #81868d; // for muted text\n --color-foreground-border: #666666; // for content borders\n\n --color-background-primary: #131416; // for content\n --color-background-secondary: #1a1c1e; // for navigation + ToC\n --color-background-hover: #1e2124ff; // for navigation-item hover\n --color-background-hover--transparent: #1e212400;\n --color-background-border: #303335; // for UI borders\n --color-background-item: #444; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #3d94ff;\n --color-brand-content: #5ca5ff;\n --color-brand-visited: #b27aeb;\n\n // Highlighted text (search)\n --color-highlighted-background: #083563;\n\n // GUI Labels\n --color-guilabel-background: #08356380;\n --color-guilabel-border: #13395f80;\n\n // API documentation\n --color-api-keyword: var(--color-foreground-secondary);\n --color-highlight-on-target: #333300;\n\n --color-api-added: #3db854;\n --color-api-added-border: #267334;\n --color-api-changed: #09b0ce;\n --color-api-changed-border: #056d80;\n --color-api-deprecated: #b1a10b;\n --color-api-deprecated-border: #6e6407;\n --color-api-removed: #ff7575;\n --color-api-removed-border: #b03b3b;\n\n // Admonitions\n --color-admonition-background: #18181a;\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: #18181a;\n --color-card-marginals-background: var(--color-background-hover);\n}\n","// This file contains the styling for making the content throughout the page,\n// including fonts, paragraphs, headings and spacing among these elements.\n\nbody\n font-family: var(--font-stack)\npre,\ncode,\nkbd,\nsamp\n font-family: var(--font-stack--monospace)\n\n// Make fonts look slightly nicer.\nbody\n -webkit-font-smoothing: antialiased\n -moz-osx-font-smoothing: grayscale\n\n// Line height from Bootstrap 4.1\narticle\n line-height: 1.5\n\n//\n// Headings\n//\nh1,\nh2,\nh3,\nh4,\nh5,\nh6\n line-height: 1.25\n font-family: var(--font-stack--headings)\n font-weight: bold\n\n border-radius: 0.5rem\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n margin-left: -0.5rem\n margin-right: -0.5rem\n padding-left: 0.5rem\n padding-right: 0.5rem\n\n + p\n margin-top: 0\n\nh1\n font-size: 2.5em\n margin-top: 1.75rem\n margin-bottom: 1rem\nh2\n font-size: 2em\n margin-top: 1.75rem\nh3\n font-size: 1.5em\nh4\n font-size: 1.25em\nh5\n font-size: 1.125em\nh6\n font-size: 1em\n\nsmall\n opacity: 75%\n font-size: 80%\n\n// Paragraph\np\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n\n// Horizontal rules\nhr.docutils\n height: 1px\n padding: 0\n margin: 2rem 0\n background-color: var(--color-background-border)\n border: 0\n\n.centered\n text-align: center\n\n// Links\na\n text-decoration: underline\n\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n &:visited\n color: var(--color-link--visited)\n text-decoration-color: var(--color-link-underline--visited)\n &:hover\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &.muted-link\n color: inherit\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &:visited\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n","// This file contains the styles for the overall layouting of the documentation\n// skeleton, including the responsive changes as well as sidebar toggles.\n//\n// This is implemented as a mobile-last design, which isn't ideal, but it is\n// reasonably good-enough and I got pretty tired by the time I'd finished this\n// to move the rules around to fix this. Shouldn't take more than 3-4 hours,\n// if you know what you're doing tho.\n\n// HACK: Not all browsers account for the scrollbar width in media queries.\n// This results in horizontal scrollbars in the breakpoint where we go\n// from displaying everything to hiding the ToC. We accomodate for this by\n// adding a bit of padding to the TOC drawer, disabling the horizontal\n// scrollbar and allowing the scrollbars to cover the padding.\n// https://www.456bereastreet.com/archive/201301/media_query_width_and_vertical_scrollbars/\n\n// HACK: Always having the scrollbar visible, prevents certain browsers from\n// causing the content to stutter horizontally between taller-than-viewport and\n// not-taller-than-viewport pages.\n\nhtml\n overflow-x: hidden\n overflow-y: scroll\n scroll-behavior: smooth\n\n.sidebar-scroll, .toc-scroll, article[role=main] *\n // Override Firefox scrollbar style\n scrollbar-width: thin\n scrollbar-color: var(--color-foreground-border) transparent\n\n // Override Chrome scrollbar styles\n &::-webkit-scrollbar\n width: 0.25rem\n height: 0.25rem\n &::-webkit-scrollbar-thumb\n background-color: var(--color-foreground-border)\n border-radius: 0.125rem\n\n//\n// Overalls\n//\nhtml,\nbody\n height: 100%\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n.skip-to-content\n position: fixed\n padding: 1rem\n border-radius: 1rem\n left: 0.25rem\n top: 0.25rem\n z-index: 40\n background: var(--color-background-primary)\n color: var(--color-foreground-primary)\n\n transform: translateY(-200%)\n transition: transform 300ms ease-in-out\n\n &:focus-within\n transform: translateY(0%)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n overflow-wrap: break-word\n\n.page\n display: flex\n // fill the viewport for pages with little content.\n min-height: 100%\n\n.mobile-header\n width: 100%\n height: var(--header-height)\n background-color: var(--color-header-background)\n color: var(--color-header-text)\n border-bottom: 1px solid var(--color-header-border)\n\n // Looks like sub-script/super-script have this, and we need this to\n // be \"on top\" of those.\n z-index: 10\n\n // We don't show the header on large screens.\n display: none\n\n // Add shadow when scrolled\n &.scrolled\n border-bottom: none\n box-shadow: 0 0 0.2rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.4rem rgba(0, 0, 0, 0.2)\n\n .header-center\n a\n color: var(--color-header-text)\n text-decoration: none\n\n.main\n display: flex\n flex: 1\n\n// Sidebar (left) also covers the entire left portion of screen.\n.sidebar-drawer\n box-sizing: border-box\n\n border-right: 1px solid var(--color-sidebar-background-border)\n background: var(--color-sidebar-background)\n\n display: flex\n justify-content: flex-end\n // These next two lines took me two days to figure out.\n width: calc((100% - #{$full-width}) / 2 + #{$sidebar-width})\n min-width: $sidebar-width\n\n// Scroll-along sidebars\n.sidebar-container,\n.toc-drawer\n box-sizing: border-box\n width: $sidebar-width\n\n.toc-drawer\n background: var(--color-toc-background)\n // See HACK described on top of this document\n padding-right: 1rem\n\n.sidebar-sticky,\n.toc-sticky\n position: sticky\n top: 0\n height: min(100%, 100vh)\n height: 100vh\n\n display: flex\n flex-direction: column\n\n.sidebar-scroll,\n.toc-scroll\n flex-grow: 1\n flex-shrink: 1\n\n overflow: auto\n scroll-behavior: smooth\n\n// Central items.\n.content\n padding: 0 $content-padding\n width: $content-width\n\n display: flex\n flex-direction: column\n justify-content: space-between\n\n.icon\n display: inline-block\n height: 1rem\n width: 1rem\n svg\n width: 100%\n height: 100%\n\n//\n// Accommodate announcement banner\n//\n.announcement\n background-color: var(--color-announcement-background)\n color: var(--color-announcement-text)\n\n height: var(--header-height)\n display: flex\n align-items: center\n overflow-x: auto\n & + .page\n min-height: calc(100% - var(--header-height))\n\n.announcement-content\n box-sizing: border-box\n padding: 0.5rem\n min-width: 100%\n white-space: nowrap\n text-align: center\n\n a\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-announcement-text)\n\n &:hover\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-link--hover)\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for theme\n////////////////////////////////////////////////////////////////////////////////\n.no-js .theme-toggle-container // don't show theme toggle if there's no JS\n display: none\n\n.theme-toggle-container\n display: flex\n\n.theme-toggle\n display: flex\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n height: 1.25rem\n width: 1.25rem\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n display: flex\n align-items: center\n justify-content: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for elements\n////////////////////////////////////////////////////////////////////////////////\n.toc-overlay-icon, .nav-overlay-icon\n display: none\n cursor: pointer\n\n .icon\n color: var(--color-foreground-secondary)\n height: 1.5rem\n width: 1.5rem\n\n.toc-header-icon, .nav-overlay-icon\n // for when we set display: flex\n justify-content: center\n align-items: center\n\n.toc-content-icon\n height: 1.5rem\n width: 1.5rem\n\n.content-icon-container\n float: right\n display: flex\n margin-top: 1.5rem\n margin-left: 1rem\n margin-bottom: 1rem\n gap: 0.5rem\n\n .edit-this-page, .view-this-page\n svg\n color: inherit\n height: 1.25rem\n width: 1.25rem\n\n.sidebar-toggle\n position: absolute\n display: none\n// \n.sidebar-toggle[name=\"__toc\"]\n left: 20px\n.sidebar-toggle:checked\n left: 40px\n// \n\n.overlay\n position: fixed\n top: 0\n width: 0\n height: 0\n\n transition: width 0ms, height 0ms, opacity 250ms ease-out\n\n opacity: 0\n background-color: rgba(0, 0, 0, 0.54)\n.sidebar-overlay\n z-index: 20\n.toc-overlay\n z-index: 40\n\n// Keep things on top and smooth.\n.sidebar-drawer\n z-index: 30\n transition: left 250ms ease-in-out\n.toc-drawer\n z-index: 50\n transition: right 250ms ease-in-out\n\n// Show the Sidebar\n#__navigation:checked\n & ~ .sidebar-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .sidebar-drawer\n top: 0\n left: 0\n // Show the toc sidebar\n#__toc:checked\n & ~ .toc-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .toc-drawer\n top: 0\n right: 0\n\n////////////////////////////////////////////////////////////////////////////////\n// Back to top\n////////////////////////////////////////////////////////////////////////////////\n.back-to-top\n text-decoration: none\n\n display: none\n position: fixed\n left: 0\n top: 1rem\n padding: 0.5rem\n padding-right: 0.75rem\n border-radius: 1rem\n font-size: 0.8125rem\n\n background: var(--color-background-primary)\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), #6b728080 0px 0px 1px 0px\n\n z-index: 10\n\n margin-left: 50%\n transform: translateX(-50%)\n svg\n height: 1rem\n width: 1rem\n fill: currentColor\n display: inline-block\n\n span\n margin-left: 0.25rem\n\n .show-back-to-top &\n display: flex\n align-items: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Responsive layouting\n////////////////////////////////////////////////////////////////////////////////\n// Make things a bit bigger on bigger screens.\n@media (min-width: $full-width + $sidebar-width)\n html\n font-size: 110%\n\n@media (max-width: $full-width)\n // Collapse \"toc\" into the icon.\n .toc-content-icon\n display: flex\n .toc-drawer\n position: fixed\n height: 100vh\n top: 0\n right: -$sidebar-width\n border-left: 1px solid var(--color-background-muted)\n .toc-tree\n border-left: none\n font-size: var(--toc-font-size--mobile)\n\n // Accomodate for a changed content width.\n .sidebar-drawer\n width: calc((100% - #{$full-width - $sidebar-width}) / 2 + #{$sidebar-width})\n\n@media (max-width: $content-padded-width + $sidebar-width)\n // Center the page\n .content\n margin-left: auto\n margin-right: auto\n padding: 0 $content-padding--small\n\n@media (max-width: $content-padded-width--small + $sidebar-width)\n // Collapse \"navigation\".\n .nav-overlay-icon\n display: flex\n .sidebar-drawer\n position: fixed\n height: 100vh\n width: $sidebar-width\n\n top: 0\n left: -$sidebar-width\n\n // Swap which icon is visible.\n .toc-header-icon, .theme-toggle-header\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\n\n // Show the header.\n .mobile-header\n position: sticky\n top: 0\n display: flex\n justify-content: space-between\n align-items: center\n\n .header-left,\n .header-right\n display: flex\n height: var(--header-height)\n padding: 0 var(--header-padding)\n label\n height: 100%\n width: 100%\n user-select: none\n\n .nav-overlay-icon .icon,\n .theme-toggle svg\n height: 1.5rem\n width: 1.5rem\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: calc(var(--header-height) + 2.5rem)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n\n@media (max-width: $content-width + 2* $content-padding--small)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n article[role=main] aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","// Overall Layout Variables\n//\n// Because CSS variables can't be used in media queries. The fact that this\n// makes the layout non-user-configurable is a good thing.\n$content-padding: 3em;\n$content-padding--small: 1em;\n$content-width: 46em;\n$sidebar-width: 15em;\n$content-padded-width: $content-width + 2 * $content-padding;\n$content-padded-width--small: $content-width + 2 * $content-padding--small;\n$full-width: $content-padded-width + 2 * $sidebar-width;\n","//\n// The design here is strongly inspired by mkdocs-material.\n.admonition, .topic\n margin: 1rem auto\n padding: 0 0.5rem 0.5rem 0.5rem\n\n background: var(--color-admonition-background)\n\n border-radius: 0.2rem\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n font-size: var(--admonition-font-size)\n\n overflow: hidden\n page-break-inside: avoid\n\n // First element should have no margin, since the title has it.\n > :nth-child(2)\n margin-top: 0\n\n // Last item should have no margin, since we'll control that w/ padding\n > :last-child\n margin-bottom: 0\n\n.admonition p.admonition-title,\np.topic-title\n position: relative\n margin: 0 -0.5rem 0.5rem\n padding-left: 2rem\n padding-right: .5rem\n padding-top: .4rem\n padding-bottom: .4rem\n\n font-weight: 500\n font-size: var(--admonition-title-font-size)\n line-height: 1.3\n\n // Our fancy icon\n &::before\n content: \"\"\n position: absolute\n left: 0.5rem\n width: 1rem\n height: 1rem\n\n// Default styles\np.admonition-title\n background-color: var(--color-admonition-title-background)\n &::before\n background-color: var(--color-admonition-title)\n mask-image: var(--icon-admonition-default)\n mask-repeat: no-repeat\n\np.topic-title\n background-color: var(--color-topic-title-background)\n &::before\n background-color: var(--color-topic-title)\n mask-image: var(--icon-topic-default)\n mask-repeat: no-repeat\n\n//\n// Variants\n//\n.admonition\n border-left: 0.2rem solid var(--color-admonition-title)\n\n @each $type, $value in $admonitions\n &.#{$type}\n border-left-color: var(--color-admonition-title--#{$type})\n > .admonition-title\n background-color: var(--color-admonition-title-background--#{$type})\n &::before\n background-color: var(--color-admonition-title--#{$type})\n mask-image: var(--icon-#{nth($value, 2)})\n\n.admonition-todo > .admonition-title\n text-transform: uppercase\n","// This file stylizes the API documentation (stuff generated by autodoc). It's\n// deeply nested due to how autodoc structures the HTML without enough classes\n// to select the relevant items.\n\n// API docs!\ndl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)\n // Tweak the spacing of all the things!\n dd\n margin-left: 2rem\n > :first-child\n margin-top: 0.125rem\n > :last-child\n margin-bottom: 0.75rem\n\n // This is used for the arguments\n .field-list\n margin-bottom: 0.75rem\n\n // \"Headings\" (like \"Parameters\" and \"Return\")\n > dt\n text-transform: uppercase\n font-size: var(--font-size--small)\n\n dd:empty\n margin-bottom: 0.5rem\n dd > ul\n margin-left: -1.2rem\n > li\n > p:nth-child(2)\n margin-top: 0\n // When the last-empty-paragraph follows a paragraph, it doesn't need\n // to augument the existing spacing.\n > p + p:last-child:empty\n margin-top: 0\n margin-bottom: 0\n\n // Colorize the elements\n > dt\n color: var(--color-api-overall)\n\n.sig:not(.sig-inline)\n font-weight: bold\n\n font-size: var(--api-font-size)\n font-family: var(--font-stack--monospace)\n\n margin-left: -0.25rem\n margin-right: -0.25rem\n padding-top: 0.25rem\n padding-bottom: 0.25rem\n padding-right: 0.5rem\n\n // These are intentionally em, to properly match the font size.\n padding-left: 3em\n text-indent: -2.5em\n\n border-radius: 0.25rem\n\n background: var(--color-api-background)\n transition: background 100ms ease-out\n\n &:hover\n background: var(--color-api-background-hover)\n\n // adjust the size of the [source] link on the right.\n a.reference\n .viewcode-link\n font-weight: normal\n width: 4.25rem\n\nem.property\n font-style: normal\n &:first-child\n color: var(--color-api-keyword)\n.sig-name\n color: var(--color-api-name)\n.sig-prename\n font-weight: normal\n color: var(--color-api-pre-name)\n.sig-paren\n color: var(--color-api-paren)\n.sig-param\n font-style: normal\n\ndiv.versionadded,\ndiv.versionchanged,\ndiv.deprecated,\ndiv.versionremoved\n border-left: 0.1875rem solid\n border-radius: 0.125rem\n\n padding-left: 0.75rem\n\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\ndiv.versionadded\n border-color: var(--color-api-added-border)\n .versionmodified\n color: var(--color-api-added)\n\ndiv.versionchanged\n border-color: var(--color-api-changed-border)\n .versionmodified\n color: var(--color-api-changed)\n\ndiv.deprecated\n border-color: var(--color-api-deprecated-border)\n .versionmodified\n color: var(--color-api-deprecated)\n\ndiv.versionremoved\n border-color: var(--color-api-removed-border)\n .versionmodified\n color: var(--color-api-removed)\n\n// Align the [docs] and [source] to the right.\n.viewcode-link, .viewcode-back\n float: right\n text-align: right\n",".line-block\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n .line-block\n margin-top: 0rem\n margin-bottom: 0rem\n padding-left: 1rem\n","// Captions\narticle p.caption,\ntable > caption,\n.code-block-caption\n font-size: var(--font-size--small)\n text-align: center\n\n// Caption above a TOCTree\n.toctree-wrapper.compound\n .caption, :not(.caption) > .caption-text\n font-size: var(--font-size--small)\n text-transform: uppercase\n\n text-align: initial\n margin-bottom: 0\n\n > ul\n margin-top: 0\n margin-bottom: 0\n","// Inline code\ncode.literal, .sig-inline\n background: var(--color-inline-code-background)\n border-radius: 0.2em\n // Make the font smaller, and use padding to recover.\n font-size: var(--font-size--small--2)\n padding: 0.1em 0.2em\n\n pre.literal-block &\n font-size: inherit\n padding: 0\n\n p &\n border: 1px solid var(--color-background-border)\n\n.sig-inline\n font-family: var(--font-stack--monospace)\n\n// Code and Literal Blocks\n$code-spacing-vertical: 0.625rem\n$code-spacing-horizontal: 0.875rem\n\n// Wraps every literal block + line numbers.\ndiv[class*=\" highlight-\"],\ndiv[class^=\"highlight-\"]\n margin: 1em 0\n display: flex\n\n .table-wrapper\n margin: 0\n padding: 0\n\npre\n margin: 0\n padding: 0\n overflow: auto\n\n // Needed to have more specificity than pygments' \"pre\" selector. :(\n article[role=\"main\"] .highlight &\n line-height: 1.5\n\n &.literal-block,\n .highlight &\n font-size: var(--code-font-size)\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n // Make it look like all the other blocks.\n &.literal-block\n margin-top: 1rem\n margin-bottom: 1rem\n\n border-radius: 0.2rem\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n\n// All code is always contained in this.\n.highlight\n width: 100%\n border-radius: 0.2rem\n\n // Make line numbers and prompts un-selectable.\n .gp, span.linenos\n user-select: none\n pointer-events: none\n\n // Expand the line-highlighting.\n .hll\n display: block\n margin-left: -$code-spacing-horizontal\n margin-right: -$code-spacing-horizontal\n padding-left: $code-spacing-horizontal\n padding-right: $code-spacing-horizontal\n\n/* Make code block captions be nicely integrated */\n.code-block-caption\n display: flex\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n border-radius: 0.25rem\n border-bottom-left-radius: 0\n border-bottom-right-radius: 0\n font-weight: 300\n border-bottom: 1px solid\n\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n border-color: var(--color-background-border)\n\n + div[class]\n margin-top: 0\n pre\n border-top-left-radius: 0\n border-top-right-radius: 0\n\n// When `html_codeblock_linenos_style` is table.\n.highlighttable\n width: 100%\n display: block\n tbody\n display: block\n\n tr\n display: flex\n\n // Line numbers\n td.linenos\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n padding: $code-spacing-vertical $code-spacing-horizontal\n padding-right: 0\n border-top-left-radius: 0.2rem\n border-bottom-left-radius: 0.2rem\n\n .linenodiv\n padding-right: $code-spacing-horizontal\n font-size: var(--code-font-size)\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n\n // Actual code\n td.code\n padding: 0\n display: block\n flex: 1\n overflow: hidden\n\n .highlight\n border-top-left-radius: 0\n border-bottom-left-radius: 0\n\n// When `html_codeblock_linenos_style` is inline.\n.highlight\n span.linenos\n display: inline-block\n padding-left: 0\n padding-right: $code-spacing-horizontal\n margin-right: $code-spacing-horizontal\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n","// Inline Footnote Reference\n.footnote-reference\n font-size: var(--font-size--small--4)\n vertical-align: super\n\n// Definition list, listing the content of each note.\n// docutils <= 0.17\ndl.footnote.brackets\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\n display: grid\n grid-template-columns: max-content auto\n dt\n margin: 0\n > .fn-backref\n margin-left: 0.25rem\n\n &:after\n content: \":\"\n\n .brackets\n &:before\n content: \"[\"\n &:after\n content: \"]\"\n\n dd\n margin: 0\n padding: 0 1rem\n\n// docutils >= 0.18\naside.footnote\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\naside.footnote > span,\ndiv.citation > span\n float: left\n font-weight: 500\n padding-right: 0.25rem\n\naside.footnote > *:not(span),\ndiv.citation > p\n margin-left: 2rem\n","//\n// Figures\n//\nimg\n box-sizing: border-box\n max-width: 100%\n height: auto\n\narticle\n figure, .figure\n border-radius: 0.2rem\n\n margin: 0\n :last-child\n margin-bottom: 0\n\n .align-left\n float: left\n clear: left\n margin: 0 1rem 1rem\n\n .align-right\n float: right\n clear: right\n margin: 0 1rem 1rem\n\n .align-default,\n .align-center\n display: block\n text-align: center\n margin-left: auto\n margin-right: auto\n\n // WELL, table needs to be stylised like a table.\n table.align-default\n display: table\n text-align: initial\n",".genindex-jumpbox, .domainindex-jumpbox\n border-top: 1px solid var(--color-background-border)\n border-bottom: 1px solid var(--color-background-border)\n padding: 0.25rem\n\n.genindex-section, .domainindex-section\n h2\n margin-top: 0.75rem\n margin-bottom: 0.5rem\n ul\n margin-top: 0\n margin-bottom: 0\n","ul,\nol\n padding-left: 1.2rem\n\n // Space lists out like paragraphs\n margin-top: 1rem\n margin-bottom: 1rem\n // reduce margins within li.\n li\n > p:first-child\n margin-top: 0.25rem\n margin-bottom: 0.25rem\n\n > p:last-child\n margin-top: 0.25rem\n\n > ul,\n > ol\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n\nol\n &.arabic\n list-style: decimal\n &.loweralpha\n list-style: lower-alpha\n &.upperalpha\n list-style: upper-alpha\n &.lowerroman\n list-style: lower-roman\n &.upperroman\n list-style: upper-roman\n\n// Don't space lists out when they're \"simple\" or in a `.. toctree::`\n.simple,\n.toctree-wrapper\n li\n > ul,\n > ol\n margin-top: 0\n margin-bottom: 0\n\n// Definition Lists\n.field-list,\n.option-list,\ndl:not([class]),\ndl.simple,\ndl.footnote,\ndl.glossary\n dt\n font-weight: 500\n margin-top: 0.25rem\n + dt\n margin-top: 0\n\n .classifier::before\n content: \":\"\n margin-left: 0.2rem\n margin-right: 0.2rem\n\n dd\n > p:first-child,\n ul\n margin-top: 0.125rem\n\n ul\n margin-bottom: 0.125rem\n",".math-wrapper\n width: 100%\n overflow-x: auto\n\ndiv.math\n position: relative\n text-align: center\n\n .headerlink,\n &:focus .headerlink\n display: none\n\n &:hover .headerlink\n display: inline-block\n\n span.eqno\n position: absolute\n right: 0.5rem\n top: 50%\n transform: translate(0, -50%)\n z-index: 1\n","// Abbreviations\nabbr[title]\n cursor: help\n\n// \"Problematic\" content, as identified by Sphinx\n.problematic\n color: var(--color-problematic)\n\n// Keyboard / Mouse \"instructions\"\nkbd:not(.compound)\n margin: 0 0.2rem\n padding: 0 0.2rem\n border-radius: 0.2rem\n border: 1px solid var(--color-foreground-border)\n color: var(--color-foreground-primary)\n vertical-align: text-bottom\n\n font-size: var(--font-size--small--3)\n display: inline-block\n\n box-shadow: 0 0.0625rem 0 rgba(0, 0, 0, 0.2), inset 0 0 0 0.125rem var(--color-background-primary)\n\n background-color: var(--color-background-secondary)\n\n// Blockquote\nblockquote\n border-left: 4px solid var(--color-background-border)\n background: var(--color-background-secondary)\n\n margin-left: 0\n margin-right: 0\n padding: 0.5rem 1rem\n\n .attribution\n font-weight: 600\n text-align: right\n\n &.pull-quote,\n &.highlights\n font-size: 1.25em\n\n &.epigraph,\n &.pull-quote\n border-left-width: 0\n border-radius: 0.5rem\n\n &.highlights\n border-left-width: 0\n background: transparent\n\n// Center align embedded-in-text images\np .reference img\n vertical-align: middle\n","p.rubric\n line-height: 1.25\n font-weight: bold\n font-size: 1.125em\n\n // For Numpy-style documentation that's got rubrics within it.\n // https://github.com/pradyunsg/furo/discussions/505\n dd &\n line-height: inherit\n font-weight: inherit\n\n font-size: var(--font-size--small)\n text-transform: uppercase\n","article .sidebar\n float: right\n clear: right\n width: 30%\n\n margin-left: 1rem\n margin-right: 0\n\n border-radius: 0.2rem\n background-color: var(--color-background-secondary)\n border: var(--color-background-border) 1px solid\n\n > *\n padding-left: 1rem\n padding-right: 1rem\n\n > ul, > ol // lists need additional padding, because bullets.\n padding-left: 2.2rem\n\n .sidebar-title\n margin: 0\n padding: 0.5rem 1rem\n border-bottom: var(--color-background-border) 1px solid\n\n font-weight: 500\n\n// TODO: subtitle\n// TODO: dedicated variables?\n","[role=main] .table-wrapper.container\n width: 100%\n overflow-x: auto\n margin-top: 1rem\n margin-bottom: 0.5rem\n padding: 0.2rem 0.2rem 0.75rem\n\ntable.docutils\n border-radius: 0.2rem\n border-spacing: 0\n border-collapse: collapse\n\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n th\n background: var(--color-table-header-background)\n\n td,\n th\n // Space things out properly\n padding: 0 0.25rem\n\n // Get the borders looking just-right.\n border-left: 1px solid var(--color-table-border)\n border-right: 1px solid var(--color-table-border)\n border-bottom: 1px solid var(--color-table-border)\n\n p\n margin: 0.25rem\n\n &:first-child\n border-left: none\n &:last-child\n border-right: none\n\n // MyST-parser tables set these classes for control of column alignment\n &.text-left\n text-align: left\n &.text-right\n text-align: right\n &.text-center\n text-align: center\n",":target\n scroll-margin-top: 2.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(2.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(2.8rem + var(--header-height))\n\n// Permalinks\n.headerlink\n font-weight: 100\n user-select: none\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ndl dt,\np.caption,\nfigcaption p,\ntable > caption,\n.code-block-caption\n > .headerlink\n margin-left: 0.5rem\n visibility: hidden\n &:hover > .headerlink\n visibility: visible\n\n // Don't change to link-like, if someone adds the contents directive.\n > .toc-backref\n color: inherit\n text-decoration-line: none\n\n// Figure and table captions are special.\nfigure:hover > figcaption > p > .headerlink,\ntable:hover > caption > .headerlink\n visibility: visible\n\n:target >, // Regular section[id] style anchors\nspan:target ~ // Non-regular span[id] style \"extra\" anchors\n h1,\n h2,\n h3,\n h4,\n h5,\n h6\n &:nth-of-type(1)\n background-color: var(--color-highlight-on-target)\n // .headerlink\n // visibility: visible\n code.literal\n background-color: transparent\n\ntable:target > caption,\nfigure:target\n background-color: var(--color-highlight-on-target)\n\n// Inline page contents\n.this-will-duplicate-information-and-it-is-still-useful-here li :target\n background-color: var(--color-highlight-on-target)\n\n// Code block permalinks\n.literal-block-wrapper:target .code-block-caption\n background-color: var(--color-highlight-on-target)\n\n// When a definition list item is selected\n//\n// There isn't really an alternative to !important here, due to the\n// high-specificity of API documentation's selector.\ndt:target\n background-color: var(--color-highlight-on-target) !important\n\n// When a footnote reference is selected\n.footnote > dt:target + dd,\n.footnote-reference:target\n background-color: var(--color-highlight-on-target)\n",".guilabel\n background-color: var(--color-guilabel-background)\n border: 1px solid var(--color-guilabel-border)\n color: var(--color-guilabel-text)\n\n padding: 0 0.3em\n border-radius: 0.5em\n font-size: 0.9em\n","// This file contains the styles used for stylizing the footer that's shown\n// below the content.\n\nfooter\n font-size: var(--font-size--small)\n display: flex\n flex-direction: column\n\n margin-top: 2rem\n\n// Bottom of page information\n.bottom-of-page\n display: flex\n align-items: center\n justify-content: space-between\n\n margin-top: 1rem\n padding-top: 1rem\n padding-bottom: 1rem\n\n color: var(--color-foreground-secondary)\n border-top: 1px solid var(--color-background-border)\n\n line-height: 1.5\n\n @media (max-width: $content-width)\n text-align: center\n flex-direction: column-reverse\n gap: 0.25rem\n\n .left-details\n font-size: var(--font-size--small)\n\n .right-details\n display: flex\n flex-direction: column\n gap: 0.25rem\n text-align: right\n\n .icons\n display: flex\n justify-content: flex-end\n gap: 0.25rem\n font-size: 1rem\n\n a\n text-decoration: none\n\n svg,\n img\n font-size: 1.125rem\n height: 1em\n width: 1em\n\n// Next/Prev page information\n.related-pages\n a\n display: flex\n align-items: center\n\n text-decoration: none\n &:hover .page-info .title\n text-decoration: underline\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n svg.furo-related-icon,\n svg.furo-related-icon > use\n flex-shrink: 0\n\n color: var(--color-foreground-border)\n\n width: 0.75rem\n height: 0.75rem\n margin: 0 0.5rem\n\n &.next-page\n max-width: 50%\n\n float: right\n clear: right\n text-align: right\n\n &.prev-page\n max-width: 50%\n\n float: left\n clear: left\n\n svg\n transform: rotate(180deg)\n\n.page-info\n display: flex\n flex-direction: column\n overflow-wrap: anywhere\n\n .next-page &\n align-items: flex-end\n\n .context\n display: flex\n align-items: center\n\n padding-bottom: 0.1rem\n\n color: var(--color-foreground-muted)\n font-size: var(--font-size--small)\n text-decoration: none\n","// This file contains the styles for the contents of the left sidebar, which\n// contains the navigation tree, logo, search etc.\n\n////////////////////////////////////////////////////////////////////////////////\n// Brand on top of the scrollable tree.\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-brand\n display: flex\n flex-direction: column\n flex-shrink: 0\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n text-decoration: none\n\n.sidebar-brand-text\n color: var(--color-sidebar-brand-text)\n overflow-wrap: break-word\n margin: var(--sidebar-item-spacing-vertical) 0\n font-size: 1.5rem\n\n.sidebar-logo-container\n margin: var(--sidebar-item-spacing-vertical) 0\n\n.sidebar-logo\n margin: 0 auto\n display: block\n max-width: 100%\n\n////////////////////////////////////////////////////////////////////////////////\n// Search\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-search-container\n display: flex\n align-items: center\n margin-top: var(--sidebar-search-space-above)\n\n position: relative\n\n background: var(--color-sidebar-search-background)\n &:hover,\n &:focus-within\n background: var(--color-sidebar-search-background--focus)\n\n &::before\n content: \"\"\n position: absolute\n left: var(--sidebar-item-spacing-horizontal)\n width: var(--sidebar-search-icon-size)\n height: var(--sidebar-search-icon-size)\n\n background-color: var(--color-sidebar-search-icon)\n mask-image: var(--icon-search)\n\n.sidebar-search\n box-sizing: border-box\n\n border: none\n border-top: 1px solid var(--color-sidebar-search-border)\n border-bottom: 1px solid var(--color-sidebar-search-border)\n\n padding-top: var(--sidebar-search-input-spacing-vertical)\n padding-bottom: var(--sidebar-search-input-spacing-vertical)\n padding-right: var(--sidebar-search-input-spacing-horizontal)\n padding-left: calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size))\n\n width: 100%\n\n color: var(--color-sidebar-search-foreground)\n background: transparent\n z-index: 10\n\n &:focus\n outline: none\n\n &::placeholder\n font-size: var(--sidebar-search-input-font-size)\n\n//\n// Hide Search Matches link\n//\n#searchbox .highlight-link\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0\n margin: 0\n text-align: center\n\n a\n color: var(--color-sidebar-search-icon)\n font-size: var(--font-size--small--2)\n\n////////////////////////////////////////////////////////////////////////////////\n// Structure/Skeleton of the navigation tree (left)\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-tree\n font-size: var(--sidebar-item-font-size)\n margin-top: var(--sidebar-tree-space-above)\n margin-bottom: var(--sidebar-item-spacing-vertical)\n\n ul\n padding: 0\n margin-top: 0\n margin-bottom: 0\n\n display: flex\n flex-direction: column\n\n list-style: none\n\n li\n position: relative\n margin: 0\n\n > ul\n margin-left: var(--sidebar-item-spacing-horizontal)\n\n .icon\n color: var(--color-sidebar-link-text)\n\n .reference\n box-sizing: border-box\n color: var(--color-sidebar-link-text)\n\n // Fill the parent.\n display: inline-block\n line-height: var(--sidebar-item-line-height)\n text-decoration: none\n\n // Don't allow long words to cause wrapping.\n overflow-wrap: anywhere\n\n height: 100%\n width: 100%\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n &:hover\n color: var(--color-sidebar-link-text)\n background: var(--color-sidebar-item-background--hover)\n\n // Add a nice little \"external-link\" arrow here.\n &.external::after\n content: url('data:image/svg+xml,')\n margin: 0 0.25rem\n vertical-align: middle\n color: var(--color-sidebar-link-text)\n\n // Make the current page reference bold.\n .current-page > .reference\n font-weight: bold\n\n label\n position: absolute\n top: 0\n right: 0\n height: var(--sidebar-item-height)\n width: var(--sidebar-expander-width)\n\n cursor: pointer\n user-select: none\n\n display: flex\n justify-content: center\n align-items: center\n\n .caption, :not(.caption) > .caption-text\n font-size: var(--sidebar-caption-font-size)\n color: var(--color-sidebar-caption-text)\n\n font-weight: bold\n text-transform: uppercase\n\n margin: var(--sidebar-caption-space-above) 0 0 0\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n // If it has children, add a bit more padding to wrap the content to avoid\n // overlapping with the + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+
+ +
+ +
+
+ +
+

Index

+
+
+ +
+
+
+ + +
+
+ + Made with Sphinx and @pradyunsg's + + Furo + +
+
+ +
+
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/in_depth.html b/docs/build/in_depth.html new file mode 100644 index 000000000..bb4f32b01 --- /dev/null +++ b/docs/build/in_depth.html @@ -0,0 +1,708 @@ + + + + + + + + + In-depth Installation Instructions (NEEDS UPDATING) - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

In-depth Installation Instructions (NEEDS UPDATING)

+
+

Install Python and Required Python Tools

+
+

Ensure some version of python is installed

+

Most operating systems (especially MacOS and Linux) will already have a version of Python installed. You can proceed directly to the next step.

+
+
+

Install pyenv and pipenv

+

First install the pyenv tool to manage python versions, and the pipenv tool to manage virtual environments. (There are other tools to use for virtual environment management, but InvenioRDM is built to work with pipenv.)

+

Instructions for Linux, MacOS, and Windows can be found here: https://www.newline.co/courses/create-a-serverless-slackbot-with-aws-lambda-and-python/installing-python-3-and-pyenv-on-macos-windows-and-linux

+
+
+

Install and enable Python 3.9.16

+

Invenio’s command line tools require a specific python version to work reliably. Currently this is python 3.9.16. At the command line, first install this python version using pyenv:

+
pyenv install 3.9.16
+
+
+

Note: It is important to use cpython. Invenio does not support other python interpreters (like pypy) and advises against using anaconda python in particular for running the RDM application.

+

Just because this python version is installed does not guarantee it will be used. Next, navigate to the directory where you cloned the source code, and set the correct python version to be used locally:

+
cd ~/path/to/directory/knowledge-commons-works
+pyenv local 3.9.16
+
+
+
+

Install the invenio-cli command line tool

+

From the same directory Use pip to install the invenio-cli python package. (Do not use pipenv yet or create a virtual environment.)

+
pip install invenio-cli
+
+
+
+
+
+
+

Install Docker 20.10.10+ and Docker-compose 1.17.0+

+
+

Linux

+

If you are using Ubuntu Linux, follow the steps for installing Docker and Docker-compose explained here: https://linux.how2shout.com/install-and-configure-docker-compose-on-ubuntu-22-04-lts-jammy/

+

You must then create a docker group and add the current user to it (so that you can run docker commands without sudo). This is required for the invenio-cli scripts to work, and it must be done for the same user that will run the cli commands:

+
sudo usermod --append --groups docker $USER
+
+
+

You will likely want to configure Docker to start on system boot with systemd.

+
+
+

MacOS

+

If you are using MacOS, follow the steps for installing Docker desktop explained here: https://docs.docker.com/desktop/install/mac-install/

+

You will then need to ensure Docker has enough memory to run all the InvenioRDM containers. In the Docker Desktop app,

+
    +
  • click settings cog icon (top bar near right)

  • +
  • set the memory slider under the “Resources” tab manually to at least 6-8GB

  • +
+

Note: The environment variable recommended in the InvenioRDM documentation for MacOS 11 Big Sur is not necessary for newer MacOS versions.

+
+
+

Fixing docker-compose “not found” error

+

With the release of compose v2, the command syntax changed from docker-compose to docker compose (a command followed by a sub-command instead of one hyphenated command). This will break the invenio-cli scripts, which use the docker-compose command and you will receive an error asking you to install the “docker-compose” package.

+

One solution on Linux systems is to install Docker Compose standalone, which uses the old docker-compose syntax:

+
sudo curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
+sudo chmod +x /usr/local/bin/docker-compose
+
+
+

Another approach is simply to alias the docker compose command to docker-compose in the configuration file for your command line shell (.bashrc, .zshrc, or whichever config file is used by your shell).

+

See further https://docs.docker.com/compose/install/other/

+
+
+

Docker log rotation

+

Regardless of your operating system, you should set up log rotation for containers to keep the size of logging files from getting out of control. Either set your default logging driver to “local” (which rotates log files automatically) or set logging configuration if you use the “json-file” logging driver. See https://docs.docker.com/config/containers/logging/configure/

+
+
+

Note about docker contexts

+

Make sure to always use the same Docker context to run all of the containers for InvenioRDM. See further, https://docs.docker.com/engine/context/working-with-contexts/

+
+
+
+

Install Node.js and NVM

+

Currently InvenioRDM (v. 11) requires Node.js version 16.19.1. The best way to install and manage Node.js versions is using the nvm version manager. You can find instructions here: https://www.freecodecamp.org/news/node-version-manager-nvm-install-guide/

+

Once nvm is installed, install the required Node.js version and set it as the active version:

+
nvm install v16.19.1
+nvm use 16.19.1
+
+
+

You may have other Node versions installed as well, so before a session working with Knowledge Commons Works it’s a good idea to make sure you’re using the correct version. On MacOS and Linux you can check +from the command line with

+
which node
+
+
+
+
+

Clone the knowledge-commons-works Code

+

Using GIT, clone this repository. You should then have a folder called knowledge-commons-works (unless you chose to name it something else) on your local computer.

+
+
+

Add and Configure an Environment File

+
+

Standardized environment variables

+

This file must include the following variables with these values:

+
INVENIO_INSTANCE_PATH=/opt/invenio/var/instance
+INVENIO_RECORD_IMPORTER_LOCAL_DATA_DIR=/
+INVENIO_RECORD_IMPORTER_DATA_DIR=/opt/invenio/var/import_data
+INVENIO_SEARCH_DOMAIN='search:9200'
+INVENIO_SITE_UI_URL="https://localhost"
+INVENIO_SITE_API_URL="https://localhost/api"
+REDIS_DOMAIN='cache:6379'
+INVENIO_SQLALCHEMY_DATABASE_URI="postgresql+psycopg2://kcworks:kcworks@db/kcworks"
+POSTGRES_USER=kcworks
+POSTGRES_DB=kcworks
+
+
+

The INVENIO_INSTANCE_PATH should be set to the full path of the instance directory where InvenioRDM will store its compiled files. Since KC Works runs inside containers, this is normally a standard folder inside the container file systems (/opt/invenio/var/instance). If you were to run InvenioRDM with the python/uwsgi processes installed on your local machine, this would be a folder inside your local virtual environment folder. For example, on MacOS this might be ~/.local/share/virtualenvs/{virtual env name}/var/instance/.

+
+
+

Variables for local credentials

+

Several variables hold random values used to secure the application, or hold passwords and email addresses supplied by the local developer:

+
INVENIO_CSRF_SECRET_SALT='..put a long random value here..'
+INVENIO_SECURITY_LOGIN_SALT='..put a long random value here..'
+INVENIO_SECRET_KEY=CHANGE_ME
+POSTGRES_PASSWORD=???
+PGADMIN_DEFAULT_EMAIL=???
+PGADMIN_DEFAULT_PASSWORD=???
+
+
+

Random values for secrets like INVENIO_SECRET_KEY can be generated in a terminal by running

+
python -c 'import secrets; print(secrets.token_hex())'
+
+
+
+

Additional environment variables with sensitive information

+

Additionally, you should add the following variables with the appropriate values obtained from the Commons administrators:

+
COMMONS_API_TOKEN=mytoken  # this must be obtained from the Commons administrators
+COMMONS_SEARCH_API_TOKEN=mytoken  # this must be obtained from the Commons administrators
+INVENIO_DATACITE_PASSWORD=myinveniodatacitepassword  # this must be obtained from the Commons administrators
+
+
+

You will also need to enter the following variable with a dummy value and then replace it with the actual value after the instance is set up. Once you have an administrative user, you can generate a token for that user in the KC Works admin ui and enter it here:

+
API_TOKEN=myapitoken
+
+
+
+
+

Additional required environment variables with paths on your local file system

+

The next variables refer to paths on your local file system that are used during local development to provide easy access to the source code of various python packages and KCWorks modules:

+
PYTHON_LOCAL_GIT_PACKAGES_PATH=/path/to/local/git/packages
+PYTHON_LOCAL_SITE_PACKAGES_PATH=/path/to/local/virtual/environment/lib/python3.12/site-packages
+
+
+

PYTHON_LOCAL_GIT_PACKAGES_PATH is the parent directory that holds cloned packages that aren’t available via pip or that have been forked by us. If you are not working with the KCWorks custom modules locally, this can be set to the folder where you cloned the KCWorks code. Otherwise, it should be the path to the parent folder containing the git repositories for the forked Invenio modules and the extra KC Works modules.

+

PYTHON_LOCAL_SITE_PACKAGES_PATH is the path to the site-packages folder in your local virtual environment. This assumes that you have run pipenv install --dev --python=3.12 in your KCWorks project folder to install the python packages locally in a virtual environment.

+
+
+
+
+

Install the Invenio Python Modules

+

Navigate to the root knowledge-commons-works folder and run

+
pipenv install --dev --python=3.12
+
+
+

Note: This installation step will take several minutes.

+

This stage

+
    +
  • creates and initializes a Python virtual environment using pipenv

  • +
  • locks the python package requirements

  • +
  • installs the Invenio python packages (with pipenv)

    +
      +
    • these packages are again installed under your virtual environment folder. On MacOS this is often ~/.local/share/virtualenvs/{virtual env name}/lib/python3.9/site-packages/. You will find several modules installed here with names that start with “invenio_”.

    • +
    +
  • +
  • installs the kcworks Python package (with pipenv)

    +
      +
    • alongside the Invenio packages you will also find a kcworks package containing any custom extensions to InvenioRDM defined in your knowledge-commons-works/sites/ folder

    • +
    +
  • +
  • installs required python dependencies (with pipenv)

  • +
+
+
+

Build and Configure the Containerized Services

+
+

Build and start the containers

+

Make sure you are in the root knowledge-commons-works folder and then run

+
docker-compose up -d
+
+
+

This step will

+
    +
  • build the docker image for the nginx web server (frontend) using ./docker/nginx/Dockerfile

  • +
  • pull remote images for other services: mq, search, db, cache, pgadmin, opensearch-dashboards

  • +
  • start containers from all of these images and mounts local files or folders into the containers as required in the docker-compose.yml and docker-services.yml files

  • +
+
+
+

Create and initialize the database, search indices, and task queue

+

Again, from the root knowledge-commons-works folder, run this command:

+
invenio-cli services setup
+
+
+

This step will

+
    +
  • create the postgresql database and table structure

  • +
  • create Invenio admin role and assigns it superuser access

  • +
  • begin indexing with OpenSearch

  • +
  • create Invenio fixtures

  • +
  • insert demo data into the database (unless you add the –no-demo-data flag)

  • +
+

Note: If for some reason you need to run this step again, you will need to add the --force flag to the docker-compose command. This tells Invenio to destroy any existing redis cache, database, index, and task queue before recreating them all. Just be aware that performing this setup again with --force will destroy all data in your database and all OpenSearch indices.

+
+
+

Start the uwsgi applications and celery worker

+

Finally, you need to start the actual applications. Knowledge Commons Works is actually run as two separate applications: one providing an html user interface, and one providing a REST api and serving JSON responses. Each application is served to the nginx web server by its own uwsgi process. The nginx server begins automatically when the frontend docker container starts, but the uwsgi applications run on your local machine and need to be started directly.

+

These applications are also supported by a Celery worker process. This is a task queue that (with the help of the RabbitMQ docker container) frees up the python applications from being blocked by long-running tasks like indexing. The celery worker also runs on your local machine and must be started directly.

+

If you want to quickly start all of these processes in the background (as daemons), you can run the kcr-startup.sh script in the root knowledge-commons-works directory:

+
bash kcr-startup.sh
+
+
+

The processes will output request and error logging to files in the logs folder of your knowledge-commons-works folder.

+

To stop these processes, simply run

+
bash kcr-shutdown.sh
+
+
+

If you would like to view the real time log output of these processes, you can also start them individually in three separate terminals:

+
pipenv run celery --app invenio_app.celery worker --beat --events --loglevel INFO
+
+
+
pipenv run uwsgi docker/uwsgi/uwsgi_ui.ini --pidfile=/tmp/kcr_ui.pid
+
+
+
pipenv run uwsgi docker/uwsgi/uwsgi_rest.ini  --pidfile=/tmp/kcr_api.pid
+
+
+

These processes can be stopped individually by pressing CTRL-C

+
+
+

Create an admin user

+

From the command line, run these commands to create and activate the admin user:

+
pipenv run invenio users create <email> --password <password>
+pipenv run invenio users activate <email>
+
+
+

If you want this user to have access to the administration panel in Invenio, you also need to run

+
pipenv run invenio access allow administration-access user <email>
+
+
+
+
+
+

Use the application!

+

You should now be able to access the following:

+
    +
  • The Knowledge Commons Works app (https://localhost)

  • +
  • The Knowledge Commons Works REST api (https://localhost/api)

  • +
  • pgAdmin for database management (https://localhost/pgadmin)

  • +
  • Opensearch Dashboards for managing search (https://localhost:5601)

  • +
+
+

Controlling the Application Services

+

Once Knowledge Commons Works is installed, you can manage its services from the command line. Note: Unless otherwise specified, the commands below must be run from the root knowledge-commons-works folder.

+
+
+

Startup and shutdown scripts

+

The bash script kcr-startup.sh will start +- the containerized services (if not running) +- the celery worker +- the two uwsgi processes +It will also ensure that you have a .env file and copy your set your INVENIO_INSTANCE_PATH variable in that file to your local instance folder, matching the instance_path variable in your .invenio.private file.

+

Simply navigate to the root knowledge-commons-works folder and run

+
bash ./kcr-startup.sh
+
+
+

To stop the processes and containerized services, simply run

+
bash ./kcr-shutdown.sh
+
+
+
+
+

Controlling just the containerized services

+

If you want to stop or start just the containerized services (rather than the local processes), you can use the invenio cli:

+
invenio-cli services start
+invenio-cli services stop
+
+
+

Or you can control them directly with the docker-compose command:

+
docker-compose up -d
+docker-compose stop
+
+
+

Note that stopping the containers this way will not destroy the data and configuration which live in docker volumes. Those volumes persist as long as the containers are not destroyed. Do not use the docker-compose down command unless you want the containers to be destroyed.

+
+
+

View logging output for uwsgi processes

+

Activity and error logging for the two uwsgi processes are written to date-stamped files in the knowledge-commons-works/logs/ folder. To watch the live logging output from one of these processes, open a new terminal in your knowledge-commons-works folder and run

+
tail -f logs/uwsgi-ui-{date}.log
+
+
+

or

+
tail -f logs/uwsgi-api-{date}.log
+
+
+
+
+

View container logging output

+

The logging output (and stdout) can be viewed with Docker Desktop using its convenient ui. It can also be viewed from the command line using:

+
docker logs <image-name> -f
+
+
+

The names of the various images are:

+
    +
  • nginx: kcworks-frontend-1

  • +
  • RabbitMQ: kcworks-mq-1

  • +
  • PostgreSQL: kcworks-db-1

  • +
  • OpenSearch: kcworks-search-1

  • +
  • Redis: kcworks-cache-1

  • +
  • OpenSearch Dashboards: kcworks-opensearch-dashboards-1

  • +
  • pgAdmin: kcworks-pgadmin-1

  • +
+
+
+

Controlling containerized nginx server

+

The frontend container is configured so that the configuration files in docker/nginx/ are bind mounted. This means that changes to those config files can be seen in the running container and enabled without rebuilding the container. To reload the nginx configuration, first enter the frontend container:

+
docker exec -it kcworks-frontend-1 bash
+
+
+

Then tell gninx to reload the config files:

+
nginx -s reload
+
+
+

You can also test the nginx config prior to reloading by running

+
nginx -t
+
+
+

Alternately, you can rebuild and restart the frontend container by running

+
docker-compose up -d --build frontend
+
+
+
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/index.html b/docs/build/index.html new file mode 100644 index 000000000..d4905ee31 --- /dev/null +++ b/docs/build/index.html @@ -0,0 +1,382 @@ + + + + + + + + + Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Welcome to Knowledge Commons Works’s documentation!

+ +
+
+

Indices and tables

+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/infrastructure.html b/docs/build/infrastructure.html new file mode 100644 index 000000000..f7b3e3709 --- /dev/null +++ b/docs/build/infrastructure.html @@ -0,0 +1,311 @@ + + + + + + + + + KCWorks Infrastructure - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

KCWorks Infrastructure

+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/installation.html b/docs/build/installation.html new file mode 100644 index 000000000..bbdd89a1a --- /dev/null +++ b/docs/build/installation.html @@ -0,0 +1,475 @@ + + + + + + + + + Installation - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Installation

+
+

Quickstart

+

These instructions allow you to run Knowledge Commons Works for local development. The app source files are copied onto your system, but the Flask application and other services (database, search, etc.) are run in Docker containers. The application is served to your browser by an nginx web server running in a separate container.

+

First you will need to have the correct versions of Docker (20.10.10+ with Docker Compose 1.17.0+) and Python (3.12.0+ with pipenv).

+

From there, installation involves these steps. Each one is further explained below, but here is a quick reference:

+
+

1. Clone the git repository

+
    +
  • From your command line, navigate to the parent folder where you want the cloned repository code to live

  • +
  • Clone the knowledge-commons-works repository with git clone git@github.com:MESH-Research/knowledge-commons-works.git && git submodule update --init

  • +
+
+

Note: Do not use the --recurse-submodules option when cloning the repository or the --recursive option when initializing the submodules. This will clone redundant copies of the inter-dependent submodules.

+
+
+
+

2. Create your configuration files

+
    +
  • cd knowledge-commons-works

  • +
  • Create and configure the .env file in this folder as described here

  • +
  • Create the .invenio.private file with the following contents:

  • +
+
[cli]
+services_setup = True
+instance_path = /opt/invenio/var/instance
+
+
+
+
+

3. Start the docker-compose project

+
    +
  • docker-compose --file docker-compose.yml up -d

  • +
+
+
+

4. Initialize the database and other services, and build asset files

+
    +
  • enter the web-ui container by running docker exec -it kcworks-ui bash

  • +
+
+

Note: The container name may be different depending on your local docker setup. You can find the correct name by running docker ps

+
+
    +
  • run the script to set up the instance services and build static assets bash ./scripts/setup-services.sh

  • +
+
+

Note: Some of the commands in this script may take a while to run. Patience is required! The invenio rdm-records fixtures command in particular may take up to an hour to complete during which time it provides no feedback. Don’t despair! It is working.

+
+
+
+

5. Create your own admin user

+
    +
  • enter the web-ui container by running docker exec -it kcworks-ui bash

  • +
+
+

Note: The container name may be different depending on your local docker setup. You can find the correct name by running docker ps

+
+
    +
  • run the commands:

  • +
+
invenio users create <email> --password <password>
+invenio users activate <email>
+invenio access allow administration-access user <email>
+
+
+
+
+

6. View the application

+
    +
  • The Knowledge Commons Works app is now running at https://localhost

  • +
  • The REST API is running at https://localhost/api

  • +
  • pgAdmin is running at https://localhost/pgadmin

  • +
  • OpenSearch Dashboards is running at https://localhost:5601

  • +
+

This setup will allow you to make changes to the core Knowledge Commons Works codebase and see those changes reflected in the running application.

+
+
+
+

Full local development setup

+

You will need to take some further steps if you want to +- Make and test changes to the various invenio modules that are included as git submodules. +- View and insert debugging statements into the code of the various core Invenio packages installed into the python environment. +To do this, you will need to do the following:

+
    +
  1. Ensure the required git submodules are cloned by running the following commands in the knowledge-commons-works folder:

    +
    git submodule update --init
    +
    +
    +

    This will clone the following repositories:

    +
    main git@github.com:MESH-Research/invenio-record-importer-kcworks.git
    +main git@github.com:MESH-Research/invenio-group-collections-kcworks.git
    +main git@github.com:MESH-Research/invenio-modular-deposit-form.git
    +main git@github.com:MESH-Research/invenio-modular-detail-page.git
    +main git@github.com:MESH-Research/invenio-remote-api-provisioner.git
    +main git@github.com:MESH-Research/invenio-remote-user-data-kcworks.git
    +local-working git@github.com:MESH-Research/invenio-communities.git
    +local-working git@github.com:MESH-Research/invenio-rdm-records.git
    +local-working git@github.com:MESH-Research/invenio-records-resources.git
    +local-working git@github.com:MESH-Research/invenio-vocabularies.git
    +
    +
    +

    These cloned repositories should then appear under the knowledge-commons-works/site/kcworks/dependencies folder.

    +
  2. +
  3. Install the python packages required by Knowldge Commons Works locally by running pipenv install in the knowledge-commons-works folder.

  4. +
  5. When you start up the docker compose project, add an additional project file to the command:

    +
      +
    • docker-compose --file docker-compose.yml --file docker-compose.dev.yml up -d +This will mount a variety of local package folders as bind mounts in your running containers. This will allow you to make changes to the python code in the cloned repositories and see those changes reflected in the running Knowledge Commons Works instance.

    • +
    +
  6. +
+
+
+

Controlling the KCWorks (Flask) application

+

The application instance and its services can be started and stopped by starting and stopping the docker-compose project:

+
docker-compose --file docker-compose.yml up -d
+
+
+
docker-compose --file docker-compose.yml stop
+
+
+
+

[!Caution] +Do not use the docker-compose down command unless you want the containers to be destroyed. This will destroy all data in your database and all OpenSearch indices. YOU DO NOT WANT TO DO THIS!

+
+

If you need to restart the main Flask application (e.g., after making configuration changes) you can do so either by stopping and restarting the docker-compose project or by running the following command inside the kcworks-ui container:

+
uwsgi --reload /tmp/uwsgi_ui.pid
+
+
+

Similarly, the REST API can be restarted by running the following command inside the web-ui container:

+
uwsgi --reload /tmp/uwsgi_api.pid
+
+
+

But these commands should not be necessary in normal operation.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/metadata.html b/docs/build/metadata.html new file mode 100644 index 000000000..0f9afadfc --- /dev/null +++ b/docs/build/metadata.html @@ -0,0 +1,1124 @@ + + + + + + + + + Metadata Schema and Vocabularies - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Metadata Schema and Vocabularies

+

The default metadata schema for InvenioRDM records is defined in the invenio-rdm-records package and documented here. It also includes a number of optional metadata fields which have been enabled in KCWorks, documented here.

+

Beyond these InvenioRDM fields, KCWorks adds a number of custom metadata fields to the schema using InvenioRDM’s custom field mechanism. These are all located in the top-level custom_fields field of the record metadata. They are prefixed with two different namespaces:

+
    +
  • kcr: custom fields that are used to store data from the KC system. These fields may be used for new data, but are not required.

  • +
  • hclegacy: custom fields that are used to store data from the legacy CORE repository. These fields must not be used for new data.

  • +
+
+

Example JSON record

+

What follows is an example of a complete metadata record (JSON object) used to create a KCWorks record. The various fields and their possible values are described in the sections below.

+

Note that no single actual record would include all of these fields. The example is provided to illustrate the structure of the metadata record and the sort of values that are valid for each field.

+
{
+    "custom_fields": {
+        "code:codeRepository": "https://github.com/my-project",
+        "code:programmingLanguage": ["Python", "JavaScript"],
+        "code:developmentStatus": "active",
+        "journal:journal": {
+            "title": "My Journal Title",
+            "issue": "2",
+            "volume": "8",
+            "pages": "123-456",
+            "issn": "0378-5955"
+        },
+        "imprint:imprint": {
+            "title": "My Book Title",
+            "pages": "458",
+            "isbn": "0-06-251587-X",
+            "place": "Lagos"
+        },
+        "meeting:meeting": {
+            "dates": "October 2022",
+            "place": "Michigan State University",
+            "title": "Fall 2022 Meeting of the Humanities Commons Working Group",
+            "acronym": "MET",
+            "url": "https://myevent.org"
+        },
+        "kcr:ai_usage": {
+            "ai_used": true,
+            "ai_description": "I used ChatGPT to generate the references."
+        },
+        "kcr:book_series": [
+            {
+                "series_title": "My series",
+                "series_volume": "8"
+            }
+        ],
+        "kcr:commons_domain": "hcommons.org",
+        "kcr:course_title": "My course",
+        "kcr:degree": "PhD",
+        "kcr:discipline": "Education",
+        "kcr:edition": "2nd",
+        "kcr:institution_department": "Education",
+        "kcr:media": [
+            "printed paper"
+        ],
+        "kcr:meeting_organization": "Humanities Commons",
+        "kcr:notes": "These are some notes about the deposit not intended for the public record.",
+        "kcr:project_title": "My project",
+        "kcr:publication_url": "https://mycourse.org",
+        "kcr:sponsoring_institution": "MSU",
+        "kcr:submitter_email": "jane.doe@hcommons.org",
+        "kcr:submitter_username": "janedoe",
+        "kcr:volumes": {
+            "total_volumes": "8",
+            "volume": "1"
+        },
+        "kcr:user_defined_tags": [
+            "Access",
+            "Digital humanities",
+            "Collaboration"
+        ]
+    },
+    "metadata": {
+        "resource_type": {
+            "id": "instructionalResource-syllabus"
+        },
+        "creators": [
+            {
+                "person_or_org": {
+                    "name": "Doe, Jane",
+                    "type": "personal",
+                    "given_name": "Jane",
+                    "family_name": "Doe",
+                    "identifiers": [
+                        {
+                            "scheme": "orcid",
+                            "identifier": "0000-0001-2345-6789"
+                        }
+                    ]
+                },
+                "role": {
+                    "id": "author"
+                },
+                "affiliations": [{"name": "Michigan State University"}]
+            }
+        ],
+        "title": "A Syllabus for a Digital Pedagogy Course",
+        "additional_titles": [
+            {
+                "title": "Teaching in the Age of AI",
+                "type": { "id": "subtitle" },
+                "lang": { "id": "eng" }
+            }
+        ],
+        "publisher": "KCWorks",
+        "publication_date": "2018/2020-09",
+        "subjects": [
+            {
+                "id": "http://id.worldcat.org/fast/958235",
+                "subject": "History",
+                "scheme": "FAST-topical"
+            },
+            {
+                "id": "http://id.worldcat.org/fast/1086436",
+                "subject": "Race",
+                "scheme": "FAST-topical"
+            },
+            {
+                "id": "http://id.worldcat.org/fast/966892",
+                "subject": "Identity (Psychology)",
+                "scheme": "FAST-topical"
+            }
+        ],
+        "contributors": [
+            {
+                "person_or_org": {
+                    "name": "John Doe",
+                    "type": "personal",
+                    "given_name": "John",
+                    "family_name": "Doe",
+                    "identifiers": [
+                        {
+                            "scheme": "orcid",
+                            "identifier": "0000-0001-2345-6780"
+                        }
+                    ]
+                },
+                "role": { "id": "other" },
+                "affiliations": [{"name": "Michigan State University"}]
+            }
+        ],
+        "dates": [
+            {
+                "date": "2025-01-01",
+                "type": { "id": "other" },
+                "description": "The date when the syllabus was made available."
+            }
+        ],
+        "formats": [
+            "application/pdf"
+        ],
+        "languages": [
+            { "id": "eng" }
+        ],
+        "identifiers": [
+            {
+                "identifier": "https://example.com/syllabus",
+                "scheme": "url"
+            }
+        ],
+        "related_identifiers": [
+            {
+                "identifier": "10.1234/foo.bar",
+                "scheme": "doi",
+                "relation_type": { "id": "iscitedby" },
+                "resource_type": { "id": "dataset" }
+            }
+        ],
+        "sizes": [
+            "11 pages",
+            "32 x 24 cm"
+        ],
+        "version": "v1.0",
+        "rights": [
+            {
+                "id": "cc-by-nc-4.0",
+                "description": {
+                    "en": "Allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited and that the re-use is not for commercial purposes."
+                },
+                "link": "https://creativecommons.org/licenses/by-nc/4.0/legalcode"
+            }
+        ],
+        "description": "<h1>A description</h1> <p>with HTML tags</p>",
+        "additional_descriptions": [
+            {
+                "description": "Some additional description about the methods involved in the syllabus.",
+                "type": {
+                    "id": "methods",
+                    "title": {
+                        "de": "Technische Informationen",
+                        "en": "Technical info"
+                    }
+                },
+                "lang": {"id": "eng", "title": {"en": "English"}}
+            }
+        ],
+        "locations": {
+            "features": [
+                {
+                    "geometry": {
+                        "type": "Point",
+                        "coordinates": [-32.94682, -60.63932]
+                    },
+                    "place": "test location place",
+                    "description": "test location description",
+                    "identifiers": [
+                        {"identifier": "12345abcde", "scheme": "wikidata"},
+                        {"identifier": "12345abcde", "scheme": "geonames"}
+                    ]
+                }
+            ]
+        },
+        "funding": [
+            {
+                "funder": {
+                    "id": "00k4n6c32",
+                },
+                "award": {
+                    "identifiers": [
+                        {
+                            "identifier": "https://sandbox.zenodo.org/",
+                            "scheme": "url"
+                        }
+                    ],
+                    "number": "111023",
+                    "title": {
+                        "en": "Launching of the research program on meaning processing"
+                    }
+                }
+            }
+        ],
+    },
+    "access": {
+        "record": "public",
+        "files": "restricted",
+        "embargo": {
+            "active": true,
+            "until": "2029-01-01",
+            "reason": "Publisher requires embargo.",
+        }
+    },
+}
+
+
+
+
+

Controlled Vocabularies

+
+

Subject headings

+
+

FAST

+

The FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) is used for the subjects field.

+
+
+

Homosaurus

+

The FAST vocabulary is augmented in KCWorks by the Homosaurus vocabulary (https://homosaurus.org/) for subjects related to sexuality and gender identity.

+
+
+
+

Organizations

+
+

ROR

+

The Research Organization Registry (https://ror.org/) is used for the organizations field.

+
+
+
+
+

Notes about Implementation of Core InvenioRDM Fields

+
+

metadata.subjects

+

Note that KCWorks employs the FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) for the subjects field, complemented by the Homosaurus vocabulary (https://homosaurus.org/).

+

The FAST vocabulary is divided into a number of sub-vocabularies called “facets”, allowing more efficient searching and less ambiguity in the subject headings. FAST subjects in the metadata.subjects array must include the complete WorldCat url for the subject heading, the standard human-readable label, and a scheme including “FAST” followed by a hyphen and the FAST facet name in lowercase: i.e., one of

+
    +
  • “FAST-topical”

  • +
  • “FAST-geographic”

  • +
  • “FAST-corporate”

  • +
  • “FAST-formgenre”

  • +
  • “FAST-event”

  • +
  • “FAST-meeting”

  • +
  • “FAST-personal”

  • +
  • “FAST-title”

  • +
  • “FAST-chronological”

  • +
+

You can search the FAST subject headings and their corresponding WorldCat urls here. The OCLC also provides helpful tools such as assignFAST, which suggests FAST subject headings based on a string (https://fast.oclc.org/assignfast/) and a converter from LCSH subject headings to FAST subject (http://fast.oclc.org/lcsh2fast).

+

Subject from the Homosaurus vocabulary must similarly include the complete homosaurus.org url as the id, the standard human-readable label as the subject, and a scheme with the value “Homosaurus”. The Homosaurus subject headings can be searched here.

+

Example:

+
{
+    "subjects": [
+        {
+            "id": "http://id.worldcat.org/fast/123456",
+            "subject": "Art History",
+            "scheme": "FAST-topical"
+        },
+        {
+            "id": "https://homosaurus.org/v3/homoit0000669",
+            "subject": "Intersex variations",
+            "scheme": "Homosaurus"
+        }
+    ]
+}
+
+
+
+
+

metadata.creators/metadata.contributors

+

Note that the KC username of a creator or contributor may be stored in the person_or_org.identifiers array of the creator or contributor object with the scheme kc_username.

+

Users are also strongly encouraged to include an ORCID identifier in the person_or_org.identifiers array with the scheme orcid.

+
+

[!Note] +The KC username is the primary link between a KCWorks record and a KC user. If you want a work to be associated with a KC user, you must include the KC username in creator or contributor object.

+
+

Example:

+
{
+    "person_or_org": {
+        "identifiers": [
+            {
+                "scheme": "kc_username",
+                "identifier": "jdoe"
+            },
+            {
+                "scheme": "orcid",
+                "identifier": "0000-0000-0000-0000"
+            }
+        ]
+    }
+}
+
+
+
+
+

KCWorks Custom Fields (kcworks/site/metadata_fields)

+
+

kcr:ai_usage

+

Type: Object[boolean, string]

+

This field stores data about any use of generative AI in the production of the record.

+

Example:

+
{
+    "kcr:ai_usage": {
+        "ai_used": true,
+        "ai_description": "This paper was edited using generative AI editing software."
+    }
+}
+
+
+
+
+

kcr:media

+

Type: Array[string]

+

This field stores a list of media or materials involved in the creation of the record. This field is used to store free-form user-defined descriptors of the media or materials and does not impose any controlled vocabulary.

+

Example:

+
{
+    "kcr:media": ["watercolor", "found objects", "audio recordings"]
+}
+
+
+
+
+

kcr:commons_domain

+

Type: string

+

This field stores the KC organizational (Commons) domain associated with the KCWorks record, if any. The record should also be placed in the KCWorks collection associated with this organization.

+

Example:

+
{
+    "kcr:commons_domain": "arlisna.hcommons.org"
+}
+
+
+
+
+

kcr:chapter_label

+

Type: string

+

This field stores the label of the chapter associated with the KCWorks record, if any. This allows us to differentiate between a simple chapter label (e.g. “Chapter 1”) and a more substantive title for the same chapter (e.g., “The Role of AI in Modern Art”).

+

Example:

+
{
+    "kcr:chapter_label": "Chapter 1"
+}
+
+
+
+
+

kcr:content_warning

+

Type: string

+

This field stores an optional content warning for the KCWorks record. This is used to flag the record for KCWorks users so that they can be aware of potentially problematic content in the record. This field is not to be used for content moderation by KCWorks moderators or admins. It is only to be used voluntarily and as desired by the record submitter.

+

Example:

+
{
+    "kcr:content_warning": "This work contains detailed accounts of abuse that may be distressing to some readers."
+}
+
+
+
+
+

kcr:course_title

+

Type: string

+

This field stores the title of the course associated with the KCWorks record. It is intended primarily for use with syllabi and instructional materials.

+

Example:

+
{
+    "kcr:course_title": "Introduction to Modern Art"
+}
+
+
+
+
+

kcr:degree

+

Type: string

+

This field stores the educational degree (e.g., PhD, DPhil, MA, etc.) associated with the KCWorks record. It is intended primarily for use with theses and dissertations.

+

Example:

+
{
+    "kcr:degree": "PhD"
+}
+
+
+
+
+

kcr:discipline

+

Type: string

+

This field stores the academic discipline associated with the KCWorks record. It is intended primarily for use with theses, dissertations, and other educational artifacts. It is not intended as a general-purpose field for describing the subject matter of the KCWorks record. For that, you should use the metadata.subjects and kcr:user_defined_tags fields.

+

This field is intended to complement the thesis:university and kcr:institution_department fields.

+

This field is not constrained by any controlled vocabulary.

+

Example:

+
{
+    "kcr:discipline": "Latin American Literature"
+}
+
+
+
+
+

kcr:edition

+

Type: string

+

This field stores a descriptor for the edition of the KCWorks record, if any.

+

Example:

+
{
+    "kcr:edition": "Second Edition"
+}
+
+
+
+
+

kcr:meeting_organization

+

Type: string

+

This field stores the name of the organization associated with the meeting or conference associated with the KCWorks record. It is intended primarily for use with conference papers, presentations, proceedings, etc.

+

Example:

+
{
+    "kcr:meeting_organization": "American Association of Art Historians"
+}
+
+
+
+
+

kcr:project_title

+

Type: string

+

This field stores the title of a project for which the KCWorks record was created. It can be used flexibly for, e.g., grant-funded projects, research projects, artistic projects, etc.

+

Example:

+
{
+    "kcr:project_title": "Kingston Poetry Residency, 2024"
+}
+
+
+
+
+

kcr:publication_url

+

Type: string (URL)

+

This field stores the URL of the publication associated with the KCWorks record. It is not the URL of the KCWorks record itself or of the work it contains. For example, if the KCWorks record contains a journal article, it would not hold the URL for the published journal article. It is intended to hold the URL of the publication as a whole that the KCWorks record is based on or is a part of. So it might hold the main URL for the journal in which the article was published, or the main URL for the book in which the chapter was published, etc.

+

This string must be a valid URL.

+

Example:

+
{
+    "kcr:publication_url": "https://www.example.com/publication/123456"
+}
+
+
+
+
+

kcr:sponsoring_institution

+

Type: string

+

This field stores the name of the institution that sponsored the KCWorks record. One intended use is for unpublished materials such white papers that were sponsored or commissioned by an institution. The field may also be used for the institution hosting a conference or workshop associated with the KCWorks record (as distinct from the organization that sponsored the event).

+

Note that this field is not intended for the degree-granting institution associated with a thesis or dissertation. That institution’s title should be stored in the thesis:university field.

+

Example:

+
{
+    "kcr:sponsoring_institution": "University of Toronto"
+}
+
+
+
+
+

kcr:submitter_email

+

Type: string (email address)

+

This field stores the email address of the submitter of the KCWorks record. It must be a valid email address.

+

Example:

+
{
+    "kcr:submitter_email": "john.doe@example.com"
+}
+
+
+
+
+

kcr:submitter_username

+

Type: string

+

This field stores the KC username of the submitter of the KCWorks record. This should be used even if the submitter is also a contributor to the KCWorks record and has included the same username in the metadata.creators.person_or_org.identifiers array.

+

Example:

+
{
+    "kcr:submitter_username": "jdoe"
+}
+
+
+
+
+

kcr:institution_department

+

Type: string

+

This field stores the institutional department in which a thesis, dissertation, or other educational artifact was produced. It is intended to complement the thesis:university field, which stores the degree-granting institution.

+

Example:

+
{
+    "kcr:institution_department": "Art History"
+}
+
+
+
+
+

kcr:book_series

+

Type: Object[string, string]

+

This field stores the title of a series that contains the KCWorks record, along with the optional volume number of the work within the series.

+

Example:

+
{
+    "kcr:book_series": {
+        "series_title": "The Complete Works of Jane Austen",
+        "series_volume": "Volume 1"
+    }
+}
+
+
+
+
+

kcr:user_defined_tags

+

Type: Array[string]

+

This field stores a list of user-defined tags for the KCWorks record. Unlike the metadata.subjects field, these tags are not constrained by any controlled vocabulary. Items should be free-form strings that describe the KCWorks record in a way that is not covered by the metadata.subjects field.

+
+

[!Note] +The kcr:user_defined_tags field is intended to supplement the metadata.subjects field, not as the primary means of describing the KCWorks record’s subject matter. Assigning proper metadata.subjects entries allows for much more effective search and discovery of the KCWorks record.

+
+

Example:

+
{
+    "kcr:user_defined_tags": ["Ukranian refugees", "Migrants in Europe"]
+}
+
+
+
+
+

kcr:commons_search_recid (system field)

+

This field is used to store the persistent identifier for the KCWorks record in the KC central search index.

+
+

[!Warning] +This field is automatically generated by the invenio-remote-api-provisioner service when a KCWorks record is published. It must not be set by the user.

+
+
+
+

kcr:commons_search_updated (system field)

+

Type: string (ISO 8601 datetime string)

+

This field stores the date and time when the KCWorks record was last updated in the KC central search index.

+
+

[!Warning] +This field is automatically generated by the invenio-remote-api-provisioner service when a KCWorks record is published. It must not be set by the user.

+
+
+
+
+

HC Legacy Custom Fields

+

The hclegacy namespace is used for custom fields that are used to store data from the legacy CORE database. These fields should not be used for new data.

+
+

custom_fields.hclegacy:groups_for_deposit

+

Type: Array[Object[string, string]]

+

This field is used to store the groups to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks collections during migration.

+

Example:

+
{
+    "hclegacy:groups_for_deposit": [
+        {
+            "group_name": "Group Name",
+            "group_identifier": "Group Identifier"
+        }
+    ]
+}
+
+
+
+
+

custom_fields.hclegacy:collection

+

Type: string

+

This field is used to store the org collection to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration.

+

Example:

+
{
+    "hclegacy:collection": "Collection Name"
+}
+
+
+
+
+

custom_fields.hclegacy:committee_deposit

+

Type: integer

+

This field is used to store the committee deposit number for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:committee_deposit": 123456
+}
+
+
+
+
+

custom_fields.hclegacy:file_location

+

Type: string

+

This field is used to store the relative path the the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:file_location": "/path/to/file.pdf"
+}
+
+
+
+
+

custom_fields.hclegacy:file_pid

+

Type: string

+

This field is used to store the persistent identifier for the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:file_pid": "hc:123456"
+}
+
+
+
+
+

custom_fields.hclegacy:previously_published

+

Type: string

+

This field is used to store the previously published status for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:previously_published": "true"
+}
+
+
+
+
+

custom_fields.hclegacy:publication_type

+

Type: string

+

This field is used to store the publication type for a legacy CORE record. It was used during migration to help determine the KCWorks resource type of the record. It is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:publication_type": "Journal Article"
+}
+
+
+
+
+

custom_fields.hclegacy:record_change_date

+

Type: string (ISO 8601 datetime string)

+

This field is used to store the date of the last change to a legacy CORE record. It was not used during migration to KCWorks and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:record_change_date": "2024-01-01T00:00:00Z"
+}
+
+
+
+
+

custom_fields.hclegacy:record_creation_date

+

Type: string (ISO 8601 datetime string)

+

This field is used to store the date of the creation of a legacy CORE record. It was not used during migration because InvenioRDM does not allow overriding of the record creation date. It is only preserved for historical purposes and should not be used for new data.

+

Example:

+
{
+    "hclegacy:record_creation_date": "2024-01-01T00:00:00Z"
+}
+
+
+
+
+

custom_fields.hclegacy:record_identifier

+

Type: string

+

This field is used to store the internal system identifier for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:record_identifier": "1001634-1263"
+}
+
+
+
+
+

custom_fields.hclegacy:submitter_org_memberships

+

Type: array[string]

+

This field is used to store the organizations to which a legacy CORE record’s submitter belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration and assign the work to those org collections.

+

Example:

+
{
+    "hclegacy:submitter_org_memberships": ["arlisna", "mla"]
+}
+
+
+
+
+

custom_fields.hclegacy:submitter_affiliation

+

Type: string

+

This field is used to store the organizational affiliation of a legacy CORE record’s submitter at the time of import into KCWorks. It was not used during migration and is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:submitter_affiliation": "University of Toronto"
+}
+
+
+
+
+

custom_fields.hclegacy:submitter_id

+

Type: string

+

This field is used to store the internal KC system user id of a legacy CORE record’s submitter. It was used during migration to assign ownership of the newly created record, and is preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:submitter_id": "123456"
+}
+
+
+
+
+

custom_fields.hclegacy:total_views

+

Type: integer

+

This field is used to store the total number of views for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:total_views": 123456
+}
+
+
+
+
+

custom_fields.hclegacy:total_downloads

+

Type: integer

+

This field is used to store the total number of downloads for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data.

+

Example:

+
{
+    "hclegacy:total_downloads": 123456
+}
+
+
+
+
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/objects.inv b/docs/build/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..f342d2c02d684c7a2d91f3f92dd3cd7f64b85a6b GIT binary patch literal 4939 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 J{{i~nV2;|zbEg0R literal 0 HcmV?d00001 diff --git a/docs/build/reference.html b/docs/build/reference.html new file mode 100644 index 000000000..11d535067 --- /dev/null +++ b/docs/build/reference.html @@ -0,0 +1,326 @@ + + + + + + + + + Reference - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Reference

+
+

InvenioRDM Documentation

+

The Knowledge Commons Works is built as an instance of InvenioRDM. The InvenioRDM Documentation, including customization and development information, can be found at https://inveniordm.docs.cern.ch/.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/docs/build/search.html b/docs/build/search.html new file mode 100644 index 000000000..2553cbc68 --- /dev/null +++ b/docs/build/search.html @@ -0,0 +1,299 @@ + + + + + + + + + +Search - Knowledge Commons Works 0.3.3 documentation + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+
+ +
+ +
+
+ + + +
+ +
+
+
+ + +
+
+ + Made with Sphinx and @pradyunsg's + + Furo + +
+
+ +
+
+ +
+
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/docs/build/searchindex.js b/docs/build/searchindex.js new file mode 100644 index 000000000..a223e31e0 --- /dev/null +++ b/docs/build/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"0.3.0-beta3 (2024-11-30)": [[0, "beta3-2024-11-30"]], "0.3.1-beta4 (2024-12-10)": [[0, "beta4-2024-12-10"]], "0.3.2-beta5 (2024-12-11)": [[0, "beta5-2024-12-11"]], "0.3.3-beta6 (2024-12-18)": [[0, "beta6-2024-12-18"]], "1. Clone the git repository": [[9, "clone-the-git-repository"]], "2. Create your configuration files": [[9, "create-your-configuration-files"]], "3. Start the docker-compose project": [[9, "start-the-docker-compose-project"]], "4. Initialize the database and other services, and build asset files": [[9, "initialize-the-database-and-other-services-and-build-asset-files"]], "5. Create your own admin user": [[9, "create-your-own-admin-user"]], "6. View the application": [[9, "view-the-application"]], "About": [[1, "about"]], "Add and Configure an Environment File": [[6, "add-and-configure-an-environment-file"]], "Adding new entry points": [[5, "adding-new-entry-points"]], "Adding new node.js packages to be included": [[5, "adding-new-node-js-packages-to-be-included"]], "Additional environment variables with sensitive information": [[6, "additional-environment-variables-with-sensitive-information"]], "Additional required environment variables with paths on your local file system": [[6, "additional-required-environment-variables-with-paths-on-your-local-file-system"]], "Build and Configure the Containerized Services": [[6, "build-and-configure-the-containerized-services"]], "Build and start the containers": [[6, "build-and-start-the-containers"]], "Bulk Record Import (invenio-record-importer-kcworks)": [[4, "bulk-record-import-invenio-record-importer-kcworks"]], "CLI Commands": [[2, "cli-commands"]], "Changes": [[0, "changes"]], "Changes to external python modules (including Invenio modules)": [[5, "changes-to-external-python-modules-including-invenio-modules"]], "Changes to html template files": [[5, "changes-to-html-template-files"]], "Changes to invenio.cfg": [[5, "changes-to-invenio-cfg"]], "Changes to python code in the site folder": [[5, "changes-to-python-code-in-the-site-folder"]], "Changes to static files": [[5, "changes-to-static-files"]], "Changes to theme (CSS) and javascript files": [[5, "changes-to-theme-css-and-javascript-files"]], "Clone the knowledge-commons-works Code": [[6, "clone-the-knowledge-commons-works-code"]], "Collections": [[4, "collections"]], "Collections for KC Groups (invenio-group-collections-kcworks)": [[4, "collections-for-kc-groups-invenio-group-collections-kcworks"]], "Commit strategy": [[5, "commit-strategy"]], "Configuration of InvenioRDM": [[3, "configuration-of-inveniordm"]], "Content moderation notifications": [[4, "content-moderation-notifications"]], "Contents:": [[7, null]], "Controlled Vocabularies": [[10, "controlled-vocabularies"]], "Controlling containerized nginx server": [[6, "controlling-containerized-nginx-server"]], "Controlling just the containerized services": [[6, "controlling-just-the-containerized-services"]], "Controlling the Application Services": [[6, "controlling-the-application-services"]], "Controlling the KCWorks (Flask) application": [[9, "controlling-the-kcworks-flask-application"]], "Copyright": [[1, "copyright"]], "Create an admin user": [[6, "create-an-admin-user"]], "Create and initialize the database, search indices, and task queue": [[6, "create-and-initialize-the-database-search-indices-and-task-queue"]], "Customizations to InvenioRDM": [[4, "customizations-to-inveniordm"]], "Deposit Form Customizations": [[4, "deposit-form-customizations"]], "Developing KCWorks": [[5, "developing-kcworks"]], "Digging deeper": [[5, "digging-deeper"]], "Docker log rotation": [[6, "docker-log-rotation"]], "Email templates": [[4, "email-templates"]], "Ensure some version of python is installed": [[6, "ensure-some-version-of-python-is-installed"]], "Example JSON record": [[10, "example-json-record"]], "FAST": [[10, "fast"]], "Fixing docker-compose \u201cnot found\u201d error": [[6, "fixing-docker-compose-not-found-error"]], "Forked Core Invenio Modules": [[4, "forked-core-invenio-modules"]], "Full local development setup": [[9, "full-local-development-setup"]], "Git Branching Strategy": [[5, "git-branching-strategy"]], "Git Submodules": [[5, "git-submodules"]], "HC Legacy Custom Fields": [[4, "hc-legacy-custom-fields"], [10, "hc-legacy-custom-fields"]], "Homosaurus": [[10, "homosaurus"]], "In-app notifications": [[4, "in-app-notifications"]], "In-depth Installation Instructions (NEEDS UPDATING)": [[6, "in-depth-installation-instructions-needs-updating"]], "Indices and tables": [[7, "indices-and-tables"]], "Install Docker 20.10.10+ and Docker-compose 1.17.0+": [[6, "install-docker-20-10-10-and-docker-compose-1-17-0"]], "Install Node.js and NVM": [[6, "install-node-js-and-nvm"]], "Install Python and Required Python Tools": [[6, "install-python-and-required-python-tools"]], "Install and enable Python 3.9.16": [[6, "install-and-enable-python-3-9-16"]], "Install pyenv and pipenv": [[6, "install-pyenv-and-pipenv"]], "Install the Invenio Python Modules": [[6, "install-the-invenio-python-modules"]], "Install the invenio-cli command line tool": [[6, "install-the-invenio-cli-command-line-tool"]], "Installation": [[9, "installation"]], "Integrations with KC": [[4, "integrations-with-kc"]], "InvenioRDM Documentation": [[11, "inveniordm-documentation"]], "Javascript tests": [[5, "javascript-tests"]], "KC Search Provisioning (invenio-remote-api-provisioner)": [[4, "kc-search-provisioning-invenio-remote-api-provisioner"]], "KCWorks Custom CLI Commands": [[2, "kcworks-custom-cli-commands"]], "KCWorks Custom Fields (kcworks/site/metadata_fields)": [[4, "kcworks-custom-fields-kcworks-site-metadata-fields"], [10, "kcworks-custom-fields-kcworks-site-metadata-fields"]], "KCWorks Infrastructure": [[8, "kcworks-infrastructure"]], "Linux": [[6, "linux"]], "MacOS": [[6, "macos"]], "Metadata Schema Customizations": [[4, "metadata-schema-customizations"]], "Metadata Schema and Vocabularies": [[10, "metadata-schema-and-vocabularies"]], "Modular Framework (invenio-modular-deposit-form)": [[4, "modular-framework-invenio-modular-deposit-form"]], "Modular Framework (invenio-modular-detail-page)": [[4, "modular-framework-invenio-modular-detail-page"]], "Naming Commits": [[5, "naming-commits"]], "Note about docker contexts": [[6, "note-about-docker-contexts"]], "Notes about Implementation of Core InvenioRDM Fields": [[4, "notes-about-implementation-of-core-inveniordm-fields"], [10, "notes-about-implementation-of-core-inveniordm-fields"]], "Notifications": [[4, "notifications"]], "Organizations": [[10, "organizations"]], "Overrides in the KCWorks Package (kcworks/site)": [[4, "overrides-in-the-kcworks-package-kcworks-site"], [4, "id1"]], "Page templates": [[4, "page-templates"]], "Python tests": [[5, "python-tests"]], "Quickstart": [[9, "quickstart"]], "ROR": [[10, "ror"]], "Rebuilding changed files on the fly (fast but limited)": [[5, "rebuilding-changed-files-on-the-fly-fast-but-limited"]], "Record Detail Page Customizations": [[4, "record-detail-page-customizations"]], "Reference": [[11, "reference"]], "Running CLI Commands in the KCWorks Container": [[2, "running-cli-commands-in-the-kcworks-container"]], "Running Invenio CLI Commands": [[2, "running-invenio-cli-commands"]], "Running automated tests (NEEDS UPDATING)": [[5, "running-automated-tests-needs-updating"]], "SAML Authentication": [[4, "saml-authentication"]], "Standardized environment variables": [[6, "standardized-environment-variables"]], "Start the uwsgi applications and celery worker": [[6, "start-the-uwsgi-applications-and-celery-worker"]], "Startup and shutdown scripts": [[6, "startup-and-shutdown-scripts"]], "Subject headings": [[10, "subject-headings"]], "Tagging Releases": [[5, "tagging-releases"]], "Template Customizations": [[4, "template-customizations"]], "The basic build process (slow)": [[5, "the-basic-build-process-slow"]], "Updating an Instance with Upstream Changes": [[5, "updating-an-instance-with-upstream-changes"]], "Updating the running KCWorks instance with development changes": [[5, "updating-the-running-kcworks-instance-with-development-changes"]], "Use the application!": [[6, "use-the-application"]], "User Data Sync (invenio-remote-user-data-kcworks)": [[4, "user-data-sync-invenio-remote-user-data-kcworks"]], "User-first-record notifications": [[4, "user-first-record-notifications"]], "Variables for local credentials": [[6, "variables-for-local-credentials"]], "Version Control": [[5, "version-control"]], "Version Numbering": [[5, "version-numbering"]], "View container logging output": [[6, "view-container-logging-output"]], "View logging output for uwsgi processes": [[6, "view-logging-output-for-uwsgi-processes"]], "Welcome to Knowledge Commons Works\u2019s documentation!": [[7, "welcome-to-knowledge-commons-works-s-documentation"]], "custom_fields.hclegacy:collection": [[4, "custom-fields-hclegacy-collection"], [10, "custom-fields-hclegacy-collection"]], "custom_fields.hclegacy:committee_deposit": [[4, "custom-fields-hclegacy-committee-deposit"], [10, "custom-fields-hclegacy-committee-deposit"]], "custom_fields.hclegacy:file_location": [[4, "custom-fields-hclegacy-file-location"], [10, "custom-fields-hclegacy-file-location"]], "custom_fields.hclegacy:file_pid": [[4, "custom-fields-hclegacy-file-pid"], [10, "custom-fields-hclegacy-file-pid"]], "custom_fields.hclegacy:groups_for_deposit": [[4, "custom-fields-hclegacy-groups-for-deposit"], [10, "custom-fields-hclegacy-groups-for-deposit"]], "custom_fields.hclegacy:previously_published": [[4, "custom-fields-hclegacy-previously-published"], [10, "custom-fields-hclegacy-previously-published"]], "custom_fields.hclegacy:publication_type": [[4, "custom-fields-hclegacy-publication-type"], [10, "custom-fields-hclegacy-publication-type"]], "custom_fields.hclegacy:record_change_date": [[4, "custom-fields-hclegacy-record-change-date"], [10, "custom-fields-hclegacy-record-change-date"]], "custom_fields.hclegacy:record_creation_date": [[4, "custom-fields-hclegacy-record-creation-date"], [10, "custom-fields-hclegacy-record-creation-date"]], "custom_fields.hclegacy:record_identifier": [[4, "custom-fields-hclegacy-record-identifier"], [10, "custom-fields-hclegacy-record-identifier"]], "custom_fields.hclegacy:submitter_affiliation": [[4, "custom-fields-hclegacy-submitter-affiliation"], [10, "custom-fields-hclegacy-submitter-affiliation"]], "custom_fields.hclegacy:submitter_id": [[4, "custom-fields-hclegacy-submitter-id"], [10, "custom-fields-hclegacy-submitter-id"]], "custom_fields.hclegacy:submitter_org_memberships": [[4, "custom-fields-hclegacy-submitter-org-memberships"], [10, "custom-fields-hclegacy-submitter-org-memberships"]], "custom_fields.hclegacy:total_downloads": [[4, "custom-fields-hclegacy-total-downloads"], [10, "custom-fields-hclegacy-total-downloads"]], "custom_fields.hclegacy:total_views": [[4, "custom-fields-hclegacy-total-views"], [10, "custom-fields-hclegacy-total-views"]], "invenio-communities": [[4, "invenio-communities"]], "invenio-rdm-records": [[4, "invenio-rdm-records"]], "invenio-records-resources": [[4, "invenio-records-resources"]], "invenio-vocabularies": [[4, "invenio-vocabularies"]], "kcr:ai_usage": [[4, "kcr-ai-usage"], [10, "kcr-ai-usage"]], "kcr:book_series": [[4, "kcr-book-series"], [10, "kcr-book-series"]], "kcr:chapter_label": [[4, "kcr-chapter-label"], [10, "kcr-chapter-label"]], "kcr:commons_domain": [[4, "kcr-commons-domain"], [10, "kcr-commons-domain"]], "kcr:commons_search_recid (system field)": [[4, "kcr-commons-search-recid-system-field"], [10, "kcr-commons-search-recid-system-field"]], "kcr:commons_search_updated (system field)": [[4, "kcr-commons-search-updated-system-field"], [10, "kcr-commons-search-updated-system-field"]], "kcr:content_warning": [[4, "kcr-content-warning"], [10, "kcr-content-warning"]], "kcr:course_title": [[4, "kcr-course-title"], [10, "kcr-course-title"]], "kcr:degree": [[4, "kcr-degree"], [10, "kcr-degree"]], "kcr:discipline": [[4, "kcr-discipline"], [10, "kcr-discipline"]], "kcr:edition": [[4, "kcr-edition"], [10, "kcr-edition"]], "kcr:institution_department": [[4, "kcr-institution-department"], [10, "kcr-institution-department"]], "kcr:media": [[4, "kcr-media"], [10, "kcr-media"]], "kcr:meeting_organization": [[4, "kcr-meeting-organization"], [10, "kcr-meeting-organization"]], "kcr:project_title": [[4, "kcr-project-title"], [10, "kcr-project-title"]], "kcr:publication_url": [[4, "kcr-publication-url"], [10, "kcr-publication-url"]], "kcr:sponsoring_institution": [[4, "kcr-sponsoring-institution"], [10, "kcr-sponsoring-institution"]], "kcr:submitter_email": [[4, "kcr-submitter-email"], [10, "kcr-submitter-email"]], "kcr:submitter_username": [[4, "kcr-submitter-username"], [10, "kcr-submitter-username"]], "kcr:user_defined_tags": [[4, "kcr-user-defined-tags"], [10, "kcr-user-defined-tags"]], "metadata.creators/metadata.contributors": [[4, "metadata-creators-metadata-contributors"], [10, "metadata-creators-metadata-contributors"]], "metadata.subjects": [[4, "metadata-subjects"], [10, "metadata-subjects"]]}, "docnames": ["CHANGES", "README", "cli_commands", "configuration", "customizations", "developing", "in_depth", "index", "infrastructure", "installation", "metadata", "reference"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["CHANGES.md", "README.md", "cli_commands.md", "configuration.md", "customizations.md", "developing.md", "in_depth.md", "index.rst", "infrastructure.md", "installation.md", "metadata.md", "reference.md"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 2, 4, 5, 6, 10], "0": [1, 5, 7, 9, 10], "00": [4, 10], "0000": [4, 10], "0001": 10, "00k4n6c32": 10, "00z": [4, 10], "01": [4, 10], "01t00": [4, 10], "0378": 10, "04": 6, "06": 10, "09": 10, "1": [4, 5, 7, 10], "10": [7, 9, 10], "1001634": [4, 10], "1086436": 10, "11": [6, 7, 10], "111023": 10, "12": [6, 7, 9], "123": 10, "1234": 10, "123456": [4, 10], "12345abcd": 10, "1263": [4, 10], "17": [7, 9], "18": 7, "19": 6, "2": [5, 6, 7, 10], "20": [7, 9], "2018": 10, "2020": 10, "2022": 10, "2023": 1, "2024": [4, 7, 10], "2025": 10, "2029": 10, "22": 6, "2345": 10, "24": [1, 10], "251587": 10, "2nd": 10, "3": [1, 5, 7], "30": 7, "32": 10, "4": 10, "456": 10, "458": 10, "5601": [6, 9], "5955": 10, "6": 6, "60": 10, "6379": 6, "63932": 10, "6780": 10, "6789": 10, "8": 10, "8601": [4, 10], "8gb": 6, "9200": 6, "94682": 10, "958235": 10, "966892": 10, "A": [0, 4, 10], "At": 6, "But": 9, "By": 5, "For": [2, 4, 5, 6, 10], "If": [4, 5, 6, 9, 10], "In": [5, 7], "It": [0, 1, 2, 4, 5, 6, 9, 10], "NOT": 9, "No": 5, "On": [2, 6], "One": [4, 6, 10], "Or": [5, 6], "TO": 9, "That": [4, 10], "The": [0, 4, 6, 9, 10, 11], "Then": [2, 5, 6], "There": [5, 6], "These": [0, 2, 4, 5, 6, 9, 10], "To": [2, 5, 6, 9], "With": [0, 6], "__init__": 5, "__name__": 5, "abl": 6, "about": [5, 7], "abov": 5, "abus": [4, 10], "academ": [1, 4, 10], "access": [0, 6, 9, 10], "account": [4, 10], "acronym": 10, "activ": [5, 6, 9, 10], "actual": [6, 10], "ad": [0, 4], "add": [0, 4, 5, 7, 9, 10], "addit": [4, 5, 9, 10], "addition": 6, "additional_descript": 10, "additional_titl": 10, "address": [4, 6, 10], "admin": [4, 10], "administr": [6, 9], "advis": 6, "affect": 0, "affili": [4, 10], "after": [5, 6, 9], "ag": 10, "again": [5, 6], "against": 6, "aggreg": [2, 4, 10], "ai": [4, 10], "ai_descript": [4, 10], "ai_us": [4, 10], "alia": 6, "alias": 5, "all": [0, 2, 4, 5, 6, 9, 10], "allow": [0, 4, 6, 9, 10], "alon": 5, "along": [4, 5, 10], "alongsid": 6, "alreadi": [5, 6], "also": [0, 2, 4, 5, 6, 10], "altern": 6, "alwai": [0, 6], "ambigu": [4, 10], "american": [4, 10], "among": 0, "an": [0, 1, 4, 7, 9, 10, 11], "anaconda": 6, "ani": [2, 4, 5, 6, 10], "anoth": 6, "api": [0, 2, 5, 6, 9, 10], "api_token": 6, "app": [6, 9], "appear": [0, 9], "append": 6, "applic": [5, 7, 10], "approach": 6, "appropri": [6, 10], "ar": [0, 2, 4, 5, 6, 9, 10], "area": [4, 10], "aren": 6, "argument": 2, "aria": 0, "arli": 0, "arlisna": [4, 10], "arrai": [4, 10], "art": [4, 10], "articl": [4, 10], "artifact": [4, 10], "artist": [4, 10], "ask": 6, "asset": 5, "assign": [4, 6, 10], "assignfast": [4, 10], "associ": [4, 10], "assum": 6, "audio": [4, 10], "augment": 10, "austen": [4, 10], "author": 10, "auto": 0, "autom": 7, "automat": [4, 5, 6, 10], "avail": [2, 5, 6, 10], "avoid": 5, "aw": 6, "awar": [4, 6, 10], "award": 10, "b": 5, "back": [0, 2, 5], "backend": 4, "background": 6, "bar": [6, 10], "base": [4, 10], "bash": [2, 5, 6, 9], "bashrc": 6, "beat": 6, "becaus": [0, 4, 5, 6, 10], "been": [0, 4, 5, 6, 10], "befor": [2, 4, 5, 6, 10], "begin": [5, 6], "being": [0, 6], "belong": [4, 10], "below": [6, 9, 10], "best": [0, 6], "beta": 5, "beta3": 7, "beta4": 7, "beta5": 7, "beta6": [1, 5, 7], "between": [4, 5, 10], "beyond": [4, 10], "big": 6, "bin": 6, "bind": [6, 9], "block": 6, "blueski": 0, "book": [4, 10], "boolean": [4, 10], "boot": 6, "both": [0, 4], "break": 6, "browser": [5, 9], "bug": [0, 5], "bugfix": 5, "build": [4, 7], "builder": 4, "built": [1, 6, 11], "bulk": [2, 7], "bundl": 5, "c": [5, 6], "cach": 6, "call": [4, 6, 10], "can": [0, 2, 4, 5, 6, 9, 10, 11], "cannot": 5, "case": [4, 5], "caution": [2, 5, 9], "cc": 10, "cd": [5, 6, 9], "central": [4, 5, 10], "cern": 11, "ch": 11, "chang": [4, 6, 7, 9, 10], "change_m": 6, "chapter": [4, 10], "chatgpt": 10, "check": [4, 6], "chmod": 6, "choos": 0, "chose": 6, "chrome": 5, "chronolog": [4, 10], "class": 4, "clean": 5, "clearer": 0, "cli": [0, 7, 9], "click": 6, "client": 5, "clone": [5, 7], "cm": 10, "co": 6, "code": [7, 9, 10], "codebas": 9, "coderepositori": 10, "cog": 6, "collabor": [1, 10], "collect": [0, 2, 5, 7, 9], "com": [4, 6, 9, 10], "command": [0, 5, 7, 9], "commerci": 10, "commiss": [4, 10], "committe": [4, 10], "common": [0, 1, 4, 5, 9, 10, 11], "commons_api_token": 6, "commons_search_api_token": 6, "commun": [0, 9], "comparison": 0, "compil": 6, "complement": [4, 10], "complet": [4, 5, 9, 10], "compon": [0, 4, 5], "compos": [5, 7], "comput": 6, "condit": 10, "conf": 5, "confer": [4, 10], "config": [4, 6], "configur": [5, 7], "confus": 0, "consid": 5, "constrain": [4, 10], "contain": [0, 4, 5, 7, 9, 10], "container": 7, "content": [9, 10], "continu": 5, "control": [4, 7], "conveni": 6, "convert": [4, 10], "coordin": 10, "copi": [5, 6, 9], "copyright": 7, "core": [2, 7, 9], "corpor": [4, 10], "correct": [2, 6, 9], "correctli": 0, "correspond": [2, 4, 10], "could": 0, "count": 2, "cours": [4, 6, 10], "cover": [4, 10], "cpython": 6, "creat": [0, 2, 4, 5, 10], "creatibutorsfield": 0, "creation": [0, 4, 10], "creativecommon": 10, "credit": 10, "ctrl": [5, 6], "curl": 6, "current": [0, 5, 6], "custom": [0, 5, 6, 7, 11], "custom_pdf_viewer_j": 5, "d": [5, 6, 9], "daemon": 6, "dashboard": [6, 9], "data": [0, 2, 5, 6, 9, 10], "databas": [2, 4, 10], "dataset": 10, "date": [0, 4, 6, 10], "datetim": [4, 10], "db": 6, "de": 10, "debug": [5, 9], "declar": 5, "deeper": 7, "default": [0, 4, 5, 6, 10], "defin": [4, 5, 6, 10], "delet": [2, 5], "demo": 6, "depart": [4, 10], "depend": [5, 6, 9], "deploi": [2, 5], "deploy": 5, "deposit": [7, 9, 10], "depth": 7, "describ": [4, 5, 9, 10], "descript": 10, "descriptor": [4, 10], "desir": [0, 4, 10], "desktop": 6, "despair": 9, "destroi": [2, 6, 9], "detail": [0, 7, 9, 10], "determin": [4, 10], "dev": [6, 9], "develop": [2, 6, 7, 11], "developmentstatu": 10, "dict": 5, "dictionari": 5, "differ": [4, 9, 10], "differenti": [4, 10], "dig": 7, "digit": 10, "direction": 4, "directli": [5, 6], "directori": 6, "discoveri": [4, 10], "displai": [0, 2], "dissert": [4, 10], "distinct": [4, 5, 10], "distress": [4, 10], "distribut": 10, "divid": [0, 2, 4, 10], "divis": 0, "do": [5, 6, 9], "doc": [5, 6, 11], "docker": [2, 5, 7], "dockerfil": 6, "document": [2, 4, 5, 6, 10], "doe": [0, 4, 5, 6, 10], "doi": [0, 10], "domain": [4, 10], "don": 9, "done": [5, 6], "down": [6, 9], "download": [4, 6, 10], "dphil": [4, 10], "draft": 4, "driver": 6, "dummi": 6, "dure": [0, 2, 4, 5, 6, 9, 10], "dynam": [2, 5], "e": [0, 2, 4, 5, 9, 10], "e2": 5, "each": [0, 4, 5, 6, 9, 10], "easi": 6, "edit": 0, "educ": [4, 10], "effect": [4, 5, 10], "effici": [4, 10], "either": [2, 6, 9], "els": 6, "email": [2, 6, 9, 10], "emailbackend": 4, "embargo": 10, "emit": 4, "emploi": [4, 5, 10], "empti": 0, "emul": 5, "en": 10, "enabl": [4, 10], "encourag": [4, 10], "end": [0, 5], "eng": 10, "engin": 6, "english": 10, "enough": 6, "ensur": [5, 9], "enter": [5, 6, 9], "entri": [4, 10], "env": [6, 9], "environ": [5, 7, 9], "error": [0, 5], "especi": [0, 5, 6], "etc": [2, 4, 5, 9, 10], "europ": [4, 10], "even": [0, 4, 10], "event": [0, 2, 4, 6, 10], "everi": 5, "exampl": [2, 4, 5, 6, 7], "except": 5, "exec": [2, 5, 6, 9], "exist": [0, 2, 5, 6], "explain": [6, 9], "export": 2, "extens": [4, 5, 6], "extra": 6, "extrem": 2, "f": 6, "facet": [4, 10], "fall": 10, "famili": 0, "family_nam": 10, "fast": 4, "featur": [5, 10], "feedback": 9, "field": [0, 7], "file": [1, 2, 4, 7, 10], "fill": 0, "final": 6, "find": [0, 2, 5, 6, 9], "first": [2, 5, 6, 9], "firstrecordcreatednotificationbuild": 4, "firstrecordcreatednotificationservic": 4, "firstrecordpublishednotificationbuild": 4, "fix": [0, 5], "fixtur": [5, 6, 9], "flag": [4, 6, 10], "flask": [2, 4, 5, 7], "flexibli": [4, 10], "flow": 5, "folder": [6, 9], "follow": [2, 4, 5, 6, 9, 10], "foo": 10, "forc": [5, 6], "fork": [6, 7], "form": [0, 7, 9, 10], "format": 10, "formgenr": [4, 10], "found": [2, 4, 10, 11], "four": 5, "free": [4, 6, 10], "freecodecamp": 6, "from": [0, 2, 4, 5, 6, 9, 10], "frontend": 6, "full": [0, 6, 7], "function": 0, "fund": [4, 10], "funder": 10, "further": [2, 6, 9], "futur": 0, "g": [0, 2, 4, 5, 9, 10], "gender": 10, "gener": [2, 4, 5, 6, 10], "geograph": [4, 10], "geometri": 10, "geonam": 10, "geopattern": 5, "get": [0, 6], "gh_page": 5, "git": 6, "github": [5, 6, 9, 10], "gitlab": 5, "given": 0, "given_nam": 10, "gninx": 6, "good": 6, "grant": [4, 10], "grep": 2, "group": [2, 5, 6, 9, 10], "group_identifi": [4, 10], "group_nam": [4, 10], "guarante": 6, "guid": 6, "h1": 10, "ha": [0, 4, 5, 6, 10], "handl": 0, "have": [0, 4, 5, 6, 9, 10], "hcommon": [4, 10], "head": 4, "header": 0, "help": [2, 4, 5, 6, 10], "here": [4, 6, 9, 10], "hidden": 0, "histor": [4, 10], "histori": [4, 5, 10], "historian": [4, 10], "hold": [4, 6, 10], "homoit0000669": [4, 10], "homosauru": 4, "host": [4, 10], "hour": 9, "how": 2, "how2shout": 6, "html": [4, 6, 10], "http": [4, 5, 6, 9, 10, 11], "human": [4, 10], "hyphen": [4, 6, 10], "i": [0, 1, 2, 4, 5, 9, 10, 11], "icon": 6, "id": [0, 4, 10], "idea": 6, "ident": 10, "identifi": [0, 4, 10], "illustr": 10, "imag": [0, 5, 6], "immedi": 5, "implement": 7, "import": [2, 5, 6, 7, 9, 10], "import_data": 6, "impos": [4, 10], "imprint": 10, "includ": [0, 1, 2, 4, 6, 9, 10, 11], "increment": 5, "index": [2, 4, 6, 7, 10], "indic": [2, 9], "individu": 6, "info": [4, 6, 10], "inform": [5, 11], "informationen": 10, "infrastructur": [0, 7], "ini": 6, "init": [5, 9], "initi": [0, 5], "insert": [6, 9], "insid": [2, 5, 6, 9], "instal": [5, 7], "instanc": [1, 2, 6, 7, 9, 11], "instance_path": [6, 9], "instead": [0, 5, 6], "institut": [4, 10], "instruct": [4, 5, 7, 9, 10], "instructionalresourc": 10, "integ": [4, 10], "integr": [5, 7], "intend": [4, 10], "inter": [5, 9], "interact": 5, "interfac": 6, "intern": [4, 10], "interpret": 6, "intersex": [4, 10], "introduc": 5, "introduct": [4, 10], "invenio": [7, 9, 10], "invenio_": 6, "invenio_app": 6, "invenio_csrf_secret_salt": 6, "invenio_custom_pdf_view": 5, "invenio_datacite_password": 6, "invenio_instance_path": 6, "invenio_notif": 4, "invenio_record_importer_data_dir": 6, "invenio_record_importer_local_data_dir": 6, "invenio_search_domain": 6, "invenio_secret_kei": 6, "invenio_security_login_salt": 6, "invenio_site_api_url": 6, "invenio_site_ui_url": 6, "invenio_sqlalchemy_database_uri": 6, "inveniordm": [1, 2, 5, 6, 7], "invert": 0, "invok": 2, "involv": [0, 4, 5, 9, 10], "isbn": 10, "iscitedbi": 10, "iso": [4, 10], "issn": 10, "issu": 10, "item": [4, 10], "its": [0, 5, 6, 9], "itself": [4, 10], "j": [0, 7], "jammi": 6, "jane": [4, 10], "janedo": 10, "javascript": 10, "jdoe": [4, 10], "jest": 5, "jinja": 4, "john": [4, 10], "journal": [4, 10], "json": [2, 5, 6, 7], "kc": [0, 2, 6, 7, 10], "kc_usernam": [4, 10], "kcr": 6, "kcr_api": 6, "kcr_ui": 6, "kcwork": [0, 6, 7], "keep": [5, 6], "keyboard": 0, "kingston": [4, 10], "knowldg": 9, "knowledg": [0, 1, 5, 9, 11], "label": [0, 4, 10], "lago": 10, "lambda": 6, "lang": 10, "languag": 10, "last": [2, 4, 5, 10], "latest": 5, "latin": [4, 10], "launch": 10, "layout": 0, "lcsh": [4, 10], "lcsh2fast": [4, 10], "lead": 0, "least": [0, 6], "leav": 5, "leftov": 5, "legaci": 2, "legalcod": 10, "less": [4, 5, 10], "level": [4, 10], "lib": 6, "licens": [1, 10], "like": [5, 6], "likewis": 5, "line": [0, 2, 9], "link": [0, 2, 4, 10], "linux": 5, "list": [2, 4, 5, 10], "literatur": [4, 10], "live": [6, 9], "load": 2, "local": [2, 5, 7], "localhost": [6, 9], "locat": [4, 5, 10], "lock": 6, "log": 4, "loglevel": 6, "logo": 0, "long": [0, 5, 6], "lost": 2, "lowercas": [4, 10], "lt": 6, "m": 5, "ma": [4, 10], "mac": 6, "machin": 6, "made": [0, 5, 10], "mai": [4, 5, 6, 9, 10], "mail": 4, "main": [0, 2, 4, 5, 9, 10], "make": [5, 6, 9], "manag": [0, 5, 6], "manual": 6, "markdown": 4, "match": [0, 6], "materi": [4, 10], "matter": [4, 10], "md": 5, "mean": [0, 4, 5, 6, 10], "meantim": 5, "mechan": [4, 10], "media": 0, "meet": [4, 10], "member": 0, "memori": 6, "menu": 0, "merg": 5, "mesh": [1, 9], "messag": 0, "met": 10, "metadata": [0, 2, 7], "method": 10, "michigan": 10, "middl": 2, "might": [0, 4, 6, 10], "migrant": [4, 10], "migrat": [4, 10], "minor": 5, "minut": 6, "miss": 0, "mit": 1, "mla": [4, 10], "modal": 0, "moder": 10, "moderatorrolerecipi": 4, "modern": [4, 10], "modifi": [0, 5], "modul": [0, 7, 9], "modular": 9, "monotask": 5, "more": [4, 5, 10], "most": [0, 5, 6], "mount": [6, 9], "mq": 6, "msu": 10, "much": [4, 10], "multipl": 0, "must": [4, 5, 6, 10], "my": 10, "myapitoken": 6, "mycours": 10, "myevent": 10, "myinveniodatacitepassword": 6, "mytoken": 6, "na": 0, "name": [0, 2, 4, 6, 9, 10], "name_parts_loc": 0, "namespac": [4, 10], "navig": [0, 5, 6, 9], "nc": 10, "necessari": [0, 6, 9], "need": [2, 7, 9], "new": [0, 4, 6, 10], "newer": 6, "newli": [4, 10], "newlin": 6, "next": [5, 6], "nginx": 9, "node": 7, "node_modul": 5, "normal": [5, 6, 9], "note": [2, 5, 7, 9], "notif": 7, "notificationop": 4, "notifications_moderator_rol": 4, "now": [0, 6, 9], "npm": 5, "number": [2, 4, 7, 10], "nvm": 7, "o": 6, "object": [4, 5, 10], "obtain": 6, "occupi": 5, "oclc": [4, 10], "octob": 10, "often": [5, 6], "old": 6, "onc": [5, 6], "one": [4, 6, 9, 10], "onli": [0, 2, 4, 5, 10], "onto": 9, "open": 6, "opengraph": 0, "opensearch": [2, 6, 9], "oper": [4, 6, 9], "opt": [5, 6, 9], "option": [0, 2, 4, 5, 9, 10], "orcid": [0, 4, 10], "order": [0, 5], "org": [4, 5, 6, 10], "organ": 4, "organiz": [4, 10], "origin": 5, "other": [0, 4, 5, 6, 10], "otherwis": 6, "out": 6, "output": 5, "over": 5, "overrid": [5, 10], "overridden": 5, "own": [5, 6], "ownership": [4, 10], "p": [2, 9, 10], "packag": [2, 6, 9, 10], "page": [0, 5, 7, 9, 10], "panel": 6, "paper": [4, 10], "parent": [6, 9], "part": [0, 1, 2, 4, 10], "particular": [6, 9], "particularli": 5, "password": [2, 6, 9], "patch": 5, "path": [4, 10], "patienc": 9, "pdf": [4, 10], "pdfj": 5, "pedagogi": 10, "pend": 0, "perform": 6, "permiss": 0, "persist": [4, 5, 6, 10], "person": [4, 10], "person_or_org": [4, 10], "pgadmin": [6, 9], "pgadmin_default_email": 6, "pgadmin_default_password": 6, "phd": [4, 10], "pick": 5, "pid": [5, 6, 9], "pidfil": 6, "pip": [5, 6], "pipenv": [5, 9], "pipfil": 5, "place": [4, 10], "plaintext": 4, "platform": 0, "poetri": [4, 10], "point": [0, 10], "possibl": [5, 10], "postgres_db": 6, "postgres_password": 6, "postgres_us": 6, "postgresql": 6, "potenti": [4, 10], "practic": 5, "prefix": [4, 10], "present": [0, 4, 10], "preserv": [4, 10], "press": 6, "previous": [0, 4, 10], "primari": [0, 4, 10], "primarili": [2, 4, 10], "print": [6, 10], "prior": [4, 6, 10], "privat": [6, 9], "problem": 5, "problemat": [4, 10], "proce": 6, "proceed": [4, 10], "process": [2, 10], "produc": [0, 2, 4, 10], "product": [2, 4, 5, 10], "profil": [0, 4], "program": 10, "programminglanguag": 10, "project": [4, 5, 6, 10], "proper": [0, 4, 10], "properti": 0, "provid": [2, 4, 5, 6, 9, 10], "provision": [9, 10], "prune": 5, "psychologi": 10, "psycopg2": 6, "public": [0, 4, 10], "publication_d": 10, "publish": [0, 4, 10], "pull": [5, 6], "purpos": [4, 10], "push": 5, "put": 6, "py": [2, 5], "pypi": 6, "pyproject": 5, "pytest": 5, "python": [7, 9, 10], "python3": 6, "python_local_git_packages_path": 6, "python_local_site_packages_path": 6, "queri": 0, "quick": 9, "quickli": 6, "quickstart": 7, "rabbitmq": 6, "race": 10, "random": [0, 6], "rather": 6, "rdm": [6, 9, 10], "rdmrecord": 4, "re": [5, 6, 10], "reach": 5, "react": 5, "read": 2, "readabl": [4, 5, 10], "reader": [4, 10], "readi": 5, "readm": 5, "real": 6, "reason": [6, 10], "rebuild": 6, "rebuilt": 5, "receiv": [4, 6], "recent": [0, 5], "recipi": 4, "recommend": 6, "record": [0, 2, 5, 7, 9], "recreat": [5, 6], "recurs": [5, 9], "redi": 6, "redis_domain": 6, "redund": [5, 9], "refactor": 0, "refer": [5, 6, 7, 9, 10], "reflect": [5, 9], "refresh": 5, "refuge": [4, 10], "regardless": 6, "registri": 10, "rel": [4, 10], "relat": [5, 10], "related_identifi": 10, "relation_typ": 10, "releas": [1, 6], "reliabl": 6, "reload": [5, 6, 9], "remot": [0, 2, 5, 6, 9, 10], "remov": 0, "replac": 6, "repo": 5, "repositori": [1, 5, 6, 10], "repres": 5, "request": [0, 5, 6], "requir": [4, 5, 7, 9, 10], "research": [1, 4, 9, 10], "resid": [4, 10], "resourc": [0, 6, 9, 10], "resource_typ": 10, "respect": 5, "respond": 5, "respons": 6, "rest": [6, 9], "restart": [5, 6, 9], "restrict": 10, "result": 0, "right": [0, 6, 10], "role": [4, 6, 10], "root": [5, 6], "rout": 0, "run": [4, 6, 7, 9], "runner": 5, "same": [4, 6, 10], "sandbox": 10, "save": 4, "schema": [0, 7], "scheme": [4, 10], "scienc": [4, 10], "script": [5, 9], "search": [0, 2, 7, 9, 10], "second": [4, 10], "secret": 6, "section": 10, "secur": 6, "see": [1, 5, 6, 9], "seen": 6, "select": 0, "selenium": 5, "self": 0, "semant": [4, 5], "semver": 5, "send": 4, "sent": 4, "separ": [5, 6, 9], "seri": [4, 10], "serial": 2, "series_titl": [4, 10], "series_volum": [4, 10], "serv": [6, 9], "server": [5, 9], "serverless": 6, "servic": [0, 2, 4, 7, 10], "services_setup": 9, "session": 6, "set": [4, 5, 6, 9, 10], "setup": [5, 6, 7], "sever": 6, "sexual": 10, "sh": [5, 6, 9], "share": [0, 1, 6], "shell": 6, "should": [0, 4, 5, 6, 9, 10], "sidebar": 0, "signal": 4, "similarli": [4, 9, 10], "simpl": [4, 10], "simpli": [5, 6], "sinc": [0, 2, 5, 6], "singl": [2, 5, 10], "site": [2, 6, 9], "size": [6, 10], "sl": 6, "slackbot": 6, "slider": 6, "so": [0, 2, 4, 5, 6, 9, 10], "social": 0, "softwar": [4, 10], "solut": 6, "solv": 0, "some": [0, 4, 5, 9, 10], "someth": 6, "sometim": [0, 5], "sort": [0, 10], "sourc": [5, 6, 9], "specif": [0, 4, 6], "specifi": 6, "sponsor": [4, 10], "squash": 5, "src": 5, "stage": [2, 5, 6], "stamp": 6, "stand": 5, "standalon": 6, "standard": [4, 10], "start": 5, "stat": [2, 4, 10], "state": 10, "statement": 9, "static": 9, "statu": [4, 10], "stdout": 6, "step": [5, 6, 9], "stop": [5, 6, 9], "store": [1, 2, 4, 5, 6, 10], "string": [0, 4, 10], "strongli": [4, 10], "structur": [6, 10], "style": 5, "sub": [2, 4, 6, 10], "submiss": 0, "submit": 0, "submitt": [4, 10], "submodul": 9, "substant": [4, 10], "subtitl": 10, "sudo": 6, "suffix": 5, "suggest": [4, 10], "suit": 5, "suitabl": 2, "superus": 6, "supplement": [4, 10], "suppli": 6, "support": [5, 6], "sur": 6, "sure": [5, 6], "syllabi": [4, 10], "syllabu": 10, "sync": 0, "syntax": 6, "synthet": 2, "system": [0, 1, 2, 5, 9], "systemd": 6, "t": [6, 9], "tab": 6, "tabl": 6, "tag": [4, 10], "tail": 6, "take": [5, 6, 9], "task": 5, "teach": 10, "technic": [0, 10], "technisch": 10, "tell": 6, "templat": 7, "temporari": 5, "termin": [5, 6], "test": [6, 7, 9, 10], "than": 6, "thei": [0, 4, 5, 10], "them": [0, 5, 6], "theses": [4, 10], "thesi": [4, 10], "thi": [0, 2, 4, 5, 6, 9, 10], "thing": 0, "those": [4, 5, 6, 9, 10], "though": 5, "three": 6, "through": 5, "time": [4, 5, 6, 9, 10], "titl": [0, 4, 10], "tmp": [5, 6, 9], "token": 6, "token_hex": 6, "toml": 5, "tool": [1, 4, 7, 10], "top": [4, 6, 10], "topic": [4, 10], "toronto": [4, 10], "total": [4, 10], "total_volum": 10, "track": 4, "true": [4, 9, 10], "try": 5, "tweak": 0, "two": [0, 4, 5, 6, 10], "txt": 1, "type": [0, 4, 10], "u": [4, 6, 10], "ubuntu": 6, "ui": [0, 2, 4, 5, 6, 9], "ukranian": [4, 10], "ultim": 5, "under": [1, 5, 6, 9], "underli": 2, "uni": 4, "unit": [4, 5], "univers": [4, 10], "unknown": 0, "unless": [5, 6, 9], "unlik": [4, 10], "unpublish": [4, 10], "unread": 4, "until": [5, 10], "up": [2, 5, 6, 9], "updat": [0, 2, 4, 7, 9, 10], "upload": [0, 5], "upstream": 7, "url": [4, 10], "us": [0, 2, 4, 5, 7, 9, 10], "usag": [2, 4, 10], "user": [0, 2, 5, 10], "usermod": 6, "usernam": [4, 10], "usr": 6, "usual": 5, "uwsgi": [5, 9], "uwsgi_api": 9, "uwsgi_rest": 6, "uwsgi_ui": [5, 6, 9], "v": [5, 6], "v1": 10, "v16": 6, "v2": 6, "v3": [4, 10], "valid": [4, 10], "valu": [0, 4, 6, 10], "var": [6, 9], "variabl": [4, 5], "variat": [4, 10], "varieti": 9, "variou": [6, 9, 10], "veri": 5, "version": [0, 1, 4, 7, 9, 10], "via": [4, 5, 6], "view": [0, 4, 5, 10], "virtual": 6, "virtualenv": 6, "visibl": [0, 5], "vocabulari": [7, 9], "volum": [4, 5, 6, 10], "voluntarili": [4, 10], "wa": [0, 4, 10], "wai": [4, 6, 10], "walk": 5, "want": [4, 5, 6, 9, 10], "warn": [2, 4, 5, 10], "watch": [5, 6], "watercolor": [4, 10], "we": 5, "web": [5, 6, 9], "webdriv": 5, "webhook": 4, "webpack": 5, "webpackthemebundl": 5, "well": [0, 4, 5, 6], "were": [0, 4, 6, 10], "what": [5, 10], "when": [0, 4, 5, 6, 9, 10], "whenev": [2, 5], "where": [0, 5, 6, 9], "wherev": 5, "whether": 4, "which": [0, 4, 5, 6, 9, 10], "whichev": 6, "while": [5, 9], "white": [4, 10], "whole": [0, 4, 10], "whose": 0, "widget": 0, "wikidata": 10, "window": [5, 6], "wip": 5, "within": [0, 4, 10], "without": [5, 6], "word": 0, "work": [0, 1, 4, 5, 9, 10, 11], "worker": [2, 5], "workshop": [4, 10], "worldcat": [4, 10], "would": [0, 2, 4, 5, 6, 10], "wrap": [0, 2], "written": 6, "wsl2": 5, "www": [4, 6, 10], "x": [6, 10], "x86_64": 6, "ye": 5, "yet": 6, "yml": [5, 6, 9], "you": [2, 4, 5, 6, 9, 10], "your": 5, "zenodo": 10, "zshrc": 6}, "titles": ["Changes", "About", "CLI Commands", "Configuration of InvenioRDM", "Customizations to InvenioRDM", "Developing KCWorks", "In-depth Installation Instructions (NEEDS UPDATING)", "Welcome to Knowledge Commons Works\u2019s documentation!", "KCWorks Infrastructure", "Installation", "Metadata Schema and Vocabularies", "Reference"], "titleterms": {"": 7, "0": [0, 6], "1": [0, 6, 9], "10": [0, 6], "11": 0, "12": 0, "16": 6, "17": 6, "18": 0, "2": [0, 9], "20": 6, "2024": 0, "3": [0, 6, 9], "30": 0, "4": 9, "5": 9, "6": 9, "9": 6, "In": [4, 6], "The": 5, "about": [1, 4, 6, 10], "ad": 5, "add": 6, "addit": 6, "admin": [6, 9], "ai_usag": [4, 10], "an": [5, 6], "api": 4, "app": 4, "applic": [6, 9], "asset": 9, "authent": 4, "autom": 5, "basic": 5, "beta3": 0, "beta4": 0, "beta5": 0, "beta6": 0, "book_seri": [4, 10], "branch": 5, "build": [5, 6, 9], "bulk": 4, "celeri": 6, "cfg": 5, "chang": [0, 5], "chapter_label": [4, 10], "cli": [2, 6], "clone": [6, 9], "code": [5, 6], "collect": [4, 10], "command": [2, 6], "commit": 5, "committee_deposit": [4, 10], "common": [6, 7], "commons_domain": [4, 10], "commons_search_recid": [4, 10], "commons_search_upd": [4, 10], "commun": 4, "compos": [6, 9], "configur": [3, 6, 9], "contain": [2, 6], "container": 6, "content": [4, 7], "content_warn": [4, 10], "context": 6, "contributor": [4, 10], "control": [5, 6, 9, 10], "copyright": 1, "core": [4, 10], "course_titl": [4, 10], "creat": [6, 9], "creator": [4, 10], "credenti": 6, "css": 5, "custom": [2, 4, 10], "custom_field": [4, 10], "data": 4, "databas": [6, 9], "deeper": 5, "degre": [4, 10], "deposit": 4, "depth": 6, "detail": 4, "develop": [5, 9], "dig": 5, "disciplin": [4, 10], "docker": [6, 9], "document": [7, 11], "edit": [4, 10], "email": 4, "enabl": 6, "ensur": 6, "entri": 5, "environ": 6, "error": 6, "exampl": 10, "extern": 5, "fast": [5, 10], "field": [4, 10], "file": [5, 6, 9], "file_loc": [4, 10], "file_pid": [4, 10], "first": 4, "fix": 6, "flask": 9, "fly": 5, "folder": 5, "fork": 4, "form": 4, "found": 6, "framework": 4, "full": 9, "git": [5, 9], "group": 4, "groups_for_deposit": [4, 10], "hc": [4, 10], "hclegaci": [4, 10], "head": 10, "homosauru": 10, "html": 5, "i": 6, "implement": [4, 10], "import": 4, "includ": 5, "indic": [6, 7], "inform": 6, "infrastructur": 8, "initi": [6, 9], "instal": [6, 9], "instanc": 5, "institution_depart": [4, 10], "instruct": 6, "integr": 4, "invenio": [2, 4, 5, 6], "inveniordm": [3, 4, 10, 11], "j": [5, 6], "javascript": 5, "json": 10, "just": 6, "kc": 4, "kcr": [4, 10], "kcwork": [2, 4, 5, 8, 9, 10], "knowledg": [6, 7], "legaci": [4, 10], "limit": 5, "line": 6, "linux": 6, "local": [6, 9], "log": 6, "maco": 6, "media": [4, 10], "meeting_organ": [4, 10], "metadata": [4, 10], "metadata_field": [4, 10], "moder": 4, "modul": [4, 5, 6], "modular": 4, "name": 5, "need": [5, 6], "new": 5, "nginx": 6, "node": [5, 6], "note": [4, 6, 10], "notif": 4, "number": 5, "nvm": 6, "organ": 10, "other": 9, "output": 6, "overrid": 4, "own": 9, "packag": [4, 5], "page": 4, "path": 6, "pipenv": 6, "point": 5, "previously_publish": [4, 10], "process": [5, 6], "project": 9, "project_titl": [4, 10], "provis": 4, "provision": 4, "publication_typ": [4, 10], "publication_url": [4, 10], "pyenv": 6, "python": [5, 6], "queue": 6, "quickstart": 9, "rdm": 4, "rebuild": 5, "record": [4, 10], "record_change_d": [4, 10], "record_creation_d": [4, 10], "record_identifi": [4, 10], "refer": 11, "releas": 5, "remot": 4, "repositori": 9, "requir": 6, "resourc": 4, "ror": 10, "rotat": 6, "run": [2, 5], "saml": 4, "schema": [4, 10], "script": 6, "search": [4, 6], "sensit": 6, "server": 6, "servic": [6, 9], "setup": 9, "shutdown": 6, "site": [4, 5, 10], "slow": 5, "some": 6, "sponsoring_institut": [4, 10], "standard": 6, "start": [6, 9], "startup": 6, "static": 5, "strategi": 5, "subject": [4, 10], "submitter_affili": [4, 10], "submitter_email": [4, 10], "submitter_id": [4, 10], "submitter_org_membership": [4, 10], "submitter_usernam": [4, 10], "submodul": 5, "sync": 4, "system": [4, 6, 10], "tabl": 7, "tag": 5, "task": 6, "templat": [4, 5], "test": 5, "theme": 5, "tool": 6, "total_download": [4, 10], "total_view": [4, 10], "updat": [5, 6], "upstream": 5, "us": 6, "user": [4, 6, 9], "user_defined_tag": [4, 10], "uwsgi": 6, "variabl": 6, "version": [5, 6], "view": [6, 9], "vocabulari": [4, 10], "welcom": 7, "work": [6, 7], "worker": 6, "your": [6, 9]}}) \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 000000000..dc1312ab0 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/README.md b/docs/source/README.md new file mode 100644 index 000000000..bba727eef --- /dev/null +++ b/docs/source/README.md @@ -0,0 +1,9 @@ +# About + +Knowledge Commons Works is a collaborative tool for storing and sharing academic research. It is part of Knowledge Commons and is built on an instance of the InvenioRDM repository system. + +Version 0.3.4-beta7 + +## Copyright + +Copyright 2023-24 Mesh Research. Released under the MIT license. (See the included LICENSE.txt file.) diff --git a/docs/source/changelog.md b/docs/source/changelog.md new file mode 100644 index 000000000..b1492bddb --- /dev/null +++ b/docs/source/changelog.md @@ -0,0 +1,80 @@ + + + + +# Changes + +## 0.3.4-beta7 (2025-01-09) + +- Upload form collection selector + - Fixed bug in collection selection modal where search results were always sorted by "newest" instead of "bestmatch" and so were useless for large result sets (original fix only worked in detail page) +- Documentation + - Moved documentation from README.md and site/CHANGES.md into a static documentation site to be served by Github Pages. + - Added more documentation for cli commands, metadata/identifiers/vocabularies, installation, and version control. +- Build system + - Pinned the version of invenio-logging to less than 2.1.2 to avoid a webpack build conflict. + +## 0.3.3-beta6 (2024-12-18) + +- Names + - Added the infrastructure to customize the division of users' names into parts so that it can be divided as desired when, e.g., the user's name is being auto-filled in the name fields of the upload form. This involves + - a new "name_parts_local" field to the user profile schema. This field contains the user's name parts if they have been modified within the KCWorks system. This is sometimes necessary when the user data synced from the remote user data service does not divide the user's name correctly. + - a cli command to update the user's name parts. + - a new "names" js module that contains functions to get the user's full name, full name in inverted order, family name, and given name from the user's name parts. + - updates to the CreatibutorsField component to use the new "names" js module and the customized name parts if they are present in a user's profile. +- Detail page + - Added missing aria-label properties for accessibility +- Collections + - Fixed wording of empty results message for collection members search + - Previously, the empty results message used "community" instead of "collection". + - Tweaks to layout of collection detail page header +- Remote user data service + - Fixed bug where user profile data was not being updated because comparison with initial data was not being made correctly. This means that, among other things, ORCID ids will now be added correctly when the user chooses "add self" on the upload form. + +## 0.3.2-beta5 (2024-12-11) + +- Added Bluesky sharing option to detail page +- Fixed line wrapping of long values in record sidebar details +- Added OpenGraph image metadata property to record detail page + - This allows social media platforms to display the KCWorks logo instead of a random image they might find on the page. + +## 0.3.1-beta4 (2024-12-10) + +- Added sort options for publication date to record search + - This allows users to sort records by the date they were published. + - It also allows publication-date sorting in API requests to the search API. Among other things, this allows users' KC profiles to display records in publication date order. +- Community selection modal bug fixes + - This affects the modal that appears both during record submission on the upload form and during collection management on the detail page. + - Fixed the sort order of search results in the modal. These were being sorted by record creation date, leading to a confusing sort order. It now sorts by "best match". This allows, e.g., "Knowledge Commons" to find the main KC collection. + - Also fixed the handling of '/' in the search query string. This allows, e.g., "ARLIS/NA" to find the ARLIS/NA collection, where previously it would produce an error. + +## 0.3.0-beta3 (2024-11-30) + +- Record detail page + - Added ui for collection management + - A new menu appears in the detail page sidebar when a user has permission to edit a record. This + allows users to manage the record's collections right from the detail page. + - With this menu users can now + - submit a request to have an existing published record added to a collection. + - add a record to multiple collections + - remove a record from some or all of its collections + - view pending collection submissions for the record + - change which collection appears as the primary collection for the record (i.e., the collection whose logo appears in the record's detail page sidebar) + - Refactored record management menu + - Refactored all sidebar menus (including the record management menu) to allow accessible + keyboard navigation + - Fixed display of event metadata + - Added display for work doi as well as version doi + - Each record has at least two DOIs: a work DOI and a version DOI. The work DOI is the DOI for the record as a whole. It always points to the most recent version of the work, even if the user creates new versions in the future. The other identifier is the version DOI, which will always point to the specific version of the work that the user is currently viewing. Previously, only the version DOI was displayed, which could be confusing if the user created a new version of the work. + +- Upload form + - Added proper messages to collections widget for published records + - since collections for published records are now managed from the detail page, the collections widget now displays messages to users pointing them to the detail page to manage collections. + - Added clearer titles to form when editing an existing record + or creating a new version + - Previously, the form would display "Editing Published Record" both when editing the metadata of an existing published version *and* when creating a new version. The header now displays "Creating New Version" when creating a new version, and "Editing Published Record" when editing the metadata of an existing published version. + - Changed default publisher from "unknown" to "Knowledge Commons" + - Previously, the default publisher was "unknown". This was especially confusing for resource types where the publisher field is hidden on the upload form. Now, the default publisher is "Knowledge Commons". + +- Solved collection links bug with custom routes + - This is a back-end technical fix that should not be visible to users. diff --git a/docs/source/cli_commands.md b/docs/source/cli_commands.md new file mode 100644 index 000000000..c81f7e29a --- /dev/null +++ b/docs/source/cli_commands.md @@ -0,0 +1,63 @@ +# CLI Commands + +## Running Invenio CLI Commands + +InvenioRDM includes a number of CLI commands that can be run from the command line. These are invoked using the `invenio` command followed by the command name and any arguments. For example, to run the `invenio users create` command, you would use the following command: + +```shell +invenio users create --password +``` + +For a list of all available CLI commands, run the following command: +```shell +invenio --help +``` + +Note that the `invenio` command wraps the underlying `flask` CLI command, so any command that can be run with `flask` can also be run with `invenio`. + +## Running CLI Commands in the KCWorks Container + +Since the main KCWorks processes are run in docker containers, you will need to run the CLI commands inside the ui container (not the worker or api containers). + +To run a CLI command in the KCWorks container during local development, you can use the following command: +```shell +docker exec -it kcworks-ui bash +invenio +``` + +On the staging and production instances, the container name is generated dynamically whenever the service is deployed. You can find the correct name by running `docker ps | grep ui` command. Then run the CLI command inside that container: +```shell +docker exec -it bash +invenio +``` + +## KCWorks Custom CLI Commands + +KCWorks includes a number of custom CLI commands that are not part of the core InvenioRDM system. Further documentation can be found by running any command with the `--help` option. + +- `invenio importer` + - **provided by the `invenio-record-importer-kcworks` package** + - bulk imports records into the KCWorks instance. + - this provides the sub-commands: + - `invenio importer serialize`: serializes records from the legacy CORE database export into a JSON file suitable for import into the KCWorks instance. + - `invenio importer load`: loads serialized records from a JSON file into the KCWorks instance. + - `invenio importer read`: reads records from the data to be imported into the KCWorks instance. + - `invenio importer create-user`: creates a KCWorks user linked to a KC user. + - `invenio importer count-records`: counts the number of records in the data to be imported. + - `invenio importer delete-records`: deletes records from the KCWorks instance. + - `invenio importer create-stats`: creates usage stats aggregations for the imported records to correspond to the records' usage before import. + - `invenio importer aggregations`: aggregates the synthetic usage events for the imported records to produce usage stats for the imported records. + +- `invenio kcworks-index destroy` + - **provided by the main KCWorks package** (kcworks/site/cli.py) + - destroys search indices for the KCWorks instance that are *not* destroyed by the main KCWorks index destroy command. These are primarily the indices for storing usage events and aggregated usage data. + - **WARNING:** This data *only* exists in the OpenSearch indices. It is not backed up by the database and will be lost if the indices are destroyed. Use this command with extreme caution. + +- `invenio kcworks-users name-parts` + - **provided by the main KCWorks package** (kcworks/site/cli.py) + - either reads or updates how KCWorks will divide a user's name into parts (e.g., first name, last name, middle name, etc.) for display in the UI and in creating record metadata. + +- `invenio user-data update` + - **provided by the `invenio-remote-user-data-kcworks` package** + - updates a single user's data from the remote KC user data service. + - with the `--groups` option, updates a group collection's metadata from the remote KC group data service. diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 000000000..4bab3886f --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,29 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "Knowledge Commons Works" +copyright = "2025, Mesh Research" +author = "Mesh Research" +release = "0.3.4" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = ["myst_parser", "sphinx.ext.autosectionlabel"] + +templates_path = ["_templates"] +exclude_patterns = [] + +autosectionlabel_prefix_document = True + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "furo" +html_static_path = ["_static"] diff --git a/docs/source/configuration.md b/docs/source/configuration.md new file mode 100644 index 000000000..c880984e2 --- /dev/null +++ b/docs/source/configuration.md @@ -0,0 +1 @@ +# Configuration of InvenioRDM diff --git a/docs/source/customizations.md b/docs/source/customizations.md new file mode 100644 index 000000000..78625678c --- /dev/null +++ b/docs/source/customizations.md @@ -0,0 +1,622 @@ +# Customizations to InvenioRDM + +## Template Customizations + +### Page templates + +### Email templates + +Custom email templates are located in `site/kcworks/templates/semantic-ui/invenio_notifications`. These override the default templates provided by InvenioRDM, and include both html and plaintext versions of each email, as well has markdown templates for other notification backends. + +Additional email templates are added for KCWorks-specific email types. + +- `user-first-record.create.jinja`: sent to KCWorks moderators when a user has created their first record. +- `user-first-record.publish.jinja`: sent to KCWorks moderators when a user's first record is published. + +## Record Detail Page Customizations + +### Modular Framework (invenio-modular-detail-page) + +### Overrides in the KCWorks Package (kcworks/site) + +## Deposit Form Customizations + +### Modular Framework (invenio-modular-deposit-form) + +### Overrides in the KCWorks Package (kcworks/site) + +## Collections + +### Collections for KC Groups (invenio-group-collections-kcworks) + +## Notifications + +### In-app notifications + +A user's unread notifications are tracked in the user's profile record. + +### Content moderation notifications + +#### User-first-record notifications + +Emails are sent to the KCWorks moderators when a user creates their first draft and publishes their first record. This is implemented using +- a custom service component for the RDMRecord service (kcworks.services.notifications.services.FirstRecordCreatedNotificationService) that runs during draft creation and publication and + - checks whether the user has any other drafts or published records. + - if not, adds a NotificationOp to the unit of work for the record operation to emit a notification of the type "user-first-record.create" or "user-first-record.publish". +- two custom notification builder classes (kcworks.services.notifications.builders.FirstRecordPublishedNotificationBuilder and kcworks.services.notifications.builders.FirstRecordCreatedNotificationBuilder) that build the notifications. + - these builders define the notification recipients using a custom ModeratorRoleRecipient generator (kcworks.services.notifications.generators.ModeratorRoleRecipient) and sends the notification to all users with the role defined in the NOTIFICATIONS_MODERATOR_ROLE config variable. + - they also define the notification backends to be used for sending the notification. In this case, a custom EmailBackend (kcworks.services.notifications.backends.EmailBackend) that sends email via the Flask-Mail extension. +- custom email templates for the notifications, located at `site/kcworks/templates/semantic-ui/invenio_notifications/`. + +## Integrations with KC + +### User Data Sync (invenio-remote-user-data-kcworks) + +User data is synced uni-directionally from KC to KCWorks. A user's data is synced with KC when +1. the user's SAML authentication info is first saved in KCWorks +2. the user logs into KCWorks +3. a webhook signal is received by KCWorks from KC + +### KC Search Provisioning (invenio-remote-api-provisioner) + +### SAML Authentication + +## Metadata Schema Customizations + +The default InvenioRDM metadata schema is defined in the `invenio-rdm-records` package and documented [here](https://inveniordm.docs.cern.ch/reference/metadata/). It also includes a number of optional metadata fields which have been enabled in KCWorks, documented [here](https://inveniordm.docs.cern.ch/reference/metadata/optional_metadata/). + +Beyond these InvenioRDM fields, KCWorks adds a number of custom metadata fields to the schema using InvenioRDM's custom field mechanism. These are all located in the top-level `custom_fields` field of the record metadata. They are prefixed with two different namespaces: +- `kcr`: custom fields that are used to store data from the KC system. These fields **may** be used for new data, but are not required. +- `hclegacy`: custom fields that are used to store data from the legacy CORE database. These fields **must not** be used for new data. + +### Notes about Implementation of Core InvenioRDM Fields + +#### metadata.subjects + +Note that KCWorks employs the FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) for the `subjects` field, complemented by the Homosaurus vocabulary (https://homosaurus.org/). + +The FAST vocabulary is divided into a number of sub-vocabularies called "facets", allowing more efficient searching and less ambiguity in the subject headings. FAST subjects in the `metadata.subjects` array must include the complete WorldCat url for the subject heading, the standard human-readable label, and a `scheme` including "FAST" followed by a hyphen and the FAST facet name in lowercase: i.e., one of +- "FAST-topical" +- "FAST-geographic" +- "FAST-corporate" +- "FAST-formgenre" +- "FAST-event" +- "FAST-meeting" +- "FAST-personal" +- "FAST-title" +- "FAST-chronological" + +You can search the FAST subject headings and their corresponding WorldCat urls [here](https://fast.oclc.org/searchfast). The OCLC also provides helpful tools such as assignFAST, which suggests FAST subject headings based on a string (https://fast.oclc.org/assignfast/) and a converter from LCSH subject headings to FAST subject (http://fast.oclc.org/lcsh2fast). + +Subject from the Homosaurus vocabulary must similarly include the complete homosaurus.org url as the `id`, the standard human-readable label as the `subject`, and a `scheme` with the value "Homosaurus". The Homosaurus subject headings can be searched [here](https://homosaurus.org/search/v3). + +Example: +```json +{ + "subjects": [ + { + "id": "http://id.worldcat.org/fast/123456", + "subject": "Art History", + "scheme": "FAST-topical" + }, + { + "id": "https://homosaurus.org/v3/homoit0000669", + "subject": "Intersex variations", + "scheme": "Homosaurus" + } + ] +} +``` + +#### metadata.creators/metadata.contributors + +Note that the KC username of a creator or contributor may be stored in the `person_or_org.identifiers` array of the creator or contributor object with the scheme `kc_username`. + +Users are also strongly encouraged to include an ORCID identifier in the `person_or_org.identifiers` array with the scheme `orcid`. + +> [!Note] +> The KC username is the primary link between a KCWorks record and a KC user. If you want a work to be associated with a KC user, you must include the KC username in creator or contributor object. + +Example: +```json +{ + "person_or_org": { + "identifiers": [ + { + "scheme": "kc_username", + "identifier": "jdoe" + }, + { + "scheme": "orcid", + "identifier": "0000-0000-0000-0000" + } + ] + } +} +``` + +### KCWorks Custom Fields (kcworks/site/metadata_fields) + +#### kcr:ai_usage + +Type: `Object[boolean, string]` + +This field stores data about any use of generative AI in the production of the record. + +Example: +```json +{ + "kcr:ai_usage": { + "ai_used": true, + "ai_description": "This paper was edited using generative AI editing software." + } +} +``` + +#### kcr:media + +Type: `Array[string]` + +This field stores a list of media or materials involved in the creation of the record. This field is used to store free-form user-defined descriptors of the media or materials and does not impose any controlled vocabulary. + +Example: +```json +{ + "kcr:media": ["watercolor", "found objects", "audio recordings"] +} +``` + +#### kcr:commons_domain + +Type: `string` + +This field stores the KC organizational (Commons) domain associated with the KCWorks record, if any. The record should also be placed in the KCWorks collection associated with this organization. + +Example: +```json +{ + "kcr:commons_domain": "arlisna.hcommons.org" +} +``` + +#### kcr:chapter_label + +Type: `string` + +This field stores the label of the chapter associated with the KCWorks record, if any. This allows us to differentiate between a simple chapter label (e.g. "Chapter 1") and a more substantive title for the same chapter (e.g., "The Role of AI in Modern Art"). + +Example: +```json +{ + "kcr:chapter_label": "Chapter 1" +} +``` + +#### kcr:content_warning + +Type: `string` + +This field stores an optional content warning for the KCWorks record. This is used to flag the record for KCWorks users so that they can be aware of potentially problematic content in the record. **This field is not to be used for content moderation by KCWorks moderators or admins. It is only to be used voluntarily and as desired by the record submitter.** + +Example: +```json +{ + "kcr:content_warning": "This work contains detailed accounts of abuse that may be distressing to some readers." +} +``` + +#### kcr:course_title + +Type: `string` + +This field stores the title of the course associated with the KCWorks record. It is intended primarily for use with syllabi and instructional materials. + +Example: +```json +{ + "kcr:course_title": "Introduction to Modern Art" +} +``` + +#### kcr:degree + +Type: `string` + +This field stores the educational degree (e.g., PhD, DPhil, MA, etc.) associated with the KCWorks record. It is intended primarily for use with theses and dissertations. + +Example: +```json +{ + "kcr:degree": "PhD" +} +``` + +#### kcr:discipline + +Type: `string` + +This field stores the academic discipline associated with the KCWorks record. It is intended primarily for use with theses, dissertations, and other educational artifacts. It is not intended as a general-purpose field for describing the subject matter of the KCWorks record. For that, you should use the `metadata.subjects` and `kcr:user_defined_tags` fields. + +This field is intended to complement the `thesis:university` and `kcr:institution_department` fields. + +This field is not constrained by any controlled vocabulary. + +Example: +```json +{ + "kcr:discipline": "Latin American Literature" +} +``` + +#### kcr:edition + +Type: `string` + +This field stores a descriptor for the edition of the KCWorks record, if any. + +Example: +```json +{ + "kcr:edition": "Second Edition" +} +``` + +#### kcr:meeting_organization + +Type: `string` + +This field stores the name of the organization associated with the meeting or conference associated with the KCWorks record. It is intended primarily for use with conference papers, presentations, proceedings, etc. + +Example: +```json +{ + "kcr:meeting_organization": "American Association of Art Historians" +} +``` + +#### kcr:project_title + +Type: `string` + +This field stores the title of a project for which the KCWorks record was created. It can be used flexibly for, e.g., grant-funded projects, research projects, artistic projects, etc. + +Example: +```json +{ + "kcr:project_title": "Kingston Poetry Residency, 2024" +} +``` + +#### kcr:publication_url + +Type: `string` (URL) + +This field stores the URL of the publication associated with the KCWorks record. It is *not* the URL of the KCWorks record itself or of the work it contains. For example, if the KCWorks record contains a journal article, it would *not* hold the URL for the published journal article. It is intended to hold the URL of the publication *as a whole* that the KCWorks record is based on or is a part of. So it might hold the main URL for the journal in which the article was published, or the main URL for the book in which the chapter was published, etc. + +This string must be a valid URL. + +Example: +```json +{ + "kcr:publication_url": "https://www.example.com/publication/123456" +} +``` + +#### kcr:sponsoring_institution + +Type: `string` + +This field stores the name of the institution that sponsored the KCWorks record. One intended use is for unpublished materials such white papers that were sponsored or commissioned by an institution. The field may also be used for the institution hosting a conference or workshop associated with the KCWorks record (as distinct from the organization that sponsored the event). + +Note that this field is not intended for the degree-granting institution associated with a thesis or dissertation. That institution's title should be stored in the `thesis:university` field. + +Example: +```json +{ + "kcr:sponsoring_institution": "University of Toronto" +} +``` + +#### kcr:submitter_email + +Type: `string` (email address) + +This field stores the email address of the submitter of the KCWorks record. It must be a valid email address. + +Example: +```json +{ + "kcr:submitter_email": "john.doe@example.com" +} +``` + +#### kcr:submitter_username + +Type: `string` + +This field stores the KC username of the submitter of the KCWorks record. This should be used even if the submitter is also a contributor to the KCWorks record and has included the same username in the `metadata.creators.person_or_org.identifiers` array. + +Example: +```json +{ + "kcr:submitter_username": "jdoe" +} +``` + +#### kcr:institution_department + +Type: `string` + +This field stores the institutional department in which a thesis, dissertation, or other educational artifact was produced. It is intended to complement the `thesis:university` field, which stores the degree-granting institution. + +Example: +```json +{ + "kcr:institution_department": "Art History" +} +``` + +#### kcr:book_series + +Type: `Object[string, string]` + +This field stores the title of a series that contains the KCWorks record, along with the optional volume number of the work within the series. + + +Example: +```json +{ + "kcr:book_series": { + "series_title": "The Complete Works of Jane Austen", + "series_volume": "Volume 1" + } +} +``` + +#### kcr:user_defined_tags + +Type: `Array[string]` + +This field stores a list of user-defined tags for the KCWorks record. Unlike the `metadata.subjects` field, these tags are not constrained by any controlled vocabulary. Items should be free-form strings that describe the KCWorks record in a way that is not covered by the `metadata.subjects` field. + +> [!Note] +> The `kcr:user_defined_tags` field is intended to supplement the `metadata.subjects` field, not as the primary means of describing the KCWorks record's subject matter. Assigning proper `metadata.subjects` entries allows for much more effective search and discovery of the KCWorks record. + +Example: +```json +{ + "kcr:user_defined_tags": ["Ukranian refugees", "Migrants in Europe"] +} +``` + +#### kcr:commons_search_recid (system field) + +This field is used to store the persistent identifier for the KCWorks record in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +#### kcr:commons_search_updated (system field) + +Type: `string` (ISO 8601 datetime string) + +This field stores the date and time when the KCWorks record was last updated in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +### HC Legacy Custom Fields + +The `hclegacy` namespace is used for custom fields that are used to store data from the legacy CORE database. These fields should not be used for new data. + +#### custom_fields.hclegacy:groups_for_deposit + +Type: `Array[Object[string, string]]` + +This field is used to store the groups to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks collections during migration. + +Example: +```json +{ + "hclegacy:groups_for_deposit": [ + { + "group_name": "Group Name", + "group_identifier": "Group Identifier" + } + ] +} +``` + +#### custom_fields.hclegacy:collection + +Type: `string` + +This field is used to store the org collection to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration. + +Example: +```json +{ + "hclegacy:collection": "Collection Name" +} +``` + +#### custom_fields.hclegacy:committee_deposit + +Type: `integer` + +This field is used to store the committee deposit number for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:committee_deposit": 123456 +} +``` + +#### custom_fields.hclegacy:file_location + +Type: `string` + +This field is used to store the relative path the the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_location": "/path/to/file.pdf" +} +``` + +#### custom_fields.hclegacy:file_pid + +Type: `string` + +This field is used to store the persistent identifier for the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_pid": "hc:123456" +} +``` + +#### custom_fields.hclegacy:previously_published + +Type: `string` + +This field is used to store the previously published status for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:previously_published": "true" +} +``` + +#### custom_fields.hclegacy:publication_type + +Type: `string` + +This field is used to store the publication type for a legacy CORE record. It was used during migration to help determine the KCWorks resource type of the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:publication_type": "Journal Article" +} +``` + +#### custom_fields.hclegacy:record_change_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the last change to a legacy CORE record. It was not used during migration to KCWorks and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_change_date": "2024-01-01T00:00:00Z" +} +``` + +#### custom_fields.hclegacy:record_creation_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the creation of a legacy CORE record. It was not used during migration because InvenioRDM does not allow overriding of the record creation date. It is only preserved for historical purposes and should not be used for new data. + +Example: +```json +{ + "hclegacy:record_creation_date": "2024-01-01T00:00:00Z" +} +``` + +#### custom_fields.hclegacy:record_identifier + +Type: `string` + +This field is used to store the internal system identifier for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_identifier": "1001634-1263" +} +``` + +#### custom_fields.hclegacy:submitter_org_memberships + +Type: `array[string]` + +This field is used to store the organizations to which a legacy CORE record's submitter belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration and assign the work to those org collections. + +Example: +```json +{ + "hclegacy:submitter_org_memberships": ["arlisna", "mla"] +} +``` + +#### custom_fields.hclegacy:submitter_affiliation + +Type: `string` + +This field is used to store the organizational affiliation of a legacy CORE record's submitter at the time of import into KCWorks. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_affiliation": "University of Toronto" +} +``` + +#### custom_fields.hclegacy:submitter_id + +Type: `string` + +This field is used to store the internal KC system user id of a legacy CORE record's submitter. It was used during migration to assign ownership of the newly created record, and is preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_id": "123456" +} +``` + +#### custom_fields.hclegacy:total_views + +Type: `integer` + +This field is used to store the total number of views for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_views": 123456 +} +``` + +#### custom_fields.hclegacy:total_downloads + +Type: `integer` + +This field is used to store the total number of downloads for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_downloads": 123456 +} +``` + +## Bulk Record Import (invenio-record-importer-kcworks) + +## Forked Core Invenio Modules + +### invenio-communities + +### invenio-rdm-records + +### invenio-records-resources + +### invenio-vocabularies diff --git a/docs/source/developing.md b/docs/source/developing.md new file mode 100644 index 000000000..b0b3834d5 --- /dev/null +++ b/docs/source/developing.md @@ -0,0 +1,259 @@ +# Developing KCWorks + +## Version Numbering + +KCWorks uses semantic versioning (https://semver.org/). When a new release is made, the version number should be incremented in the following files: + +- `README.md` +- `docs/source/README.md` +- `docs/source/conf.py` +- `site/pyproject.toml` +- `site/kcworks/__init__.py` + +While in beta, the version number should be followed by a numbered `-beta` suffix: e.g., `0.3.3-beta6`. This suffix should be updated continuously (without starting over again for minor releases) until version 1.0.0 is reached and KCWorks leaves beta. + +Bug fixes and other changes that do not introduce new features (including changes to documentation, build processes, etc.) should be considered `patch` releases. + +New features should be considered `minor` releases. + +## Version Control + +### Git Branching Strategy + +KCWorks employs a modified version of the Gitlab Flow branching strategy for version control. The repository has four persistent branches: + +- `main` is the default branch and is the reference point for active development. It will usually not be ready for production deployment. +- `staging` is the branch that is deployed to the staging server. It is created from the `main` branch when changes are ready to be tested. No commits should be made directly to the `staging` branch except to merge changes from `main`. +- `production` is the branch that is deployed to the development server. It is created from the `staging` branch when changes are ready to be deployed to the production server. No commits should be made directly to the `production` branch except to merge changes from `staging`. +- `gh_pages` is the branch that is used to generate the static documentation site for KCWorks on Github Pages. This branch is automatically updated from the `main` branch. + +New changes should be made to the `main` branch or to a temporary `feature` or `bugfix` branch created from the `main` branch. These temporary branches should be merged back into `main` as often as possible, and the temporary branches deleted. + +No commits should be made directly to the `staging` or `production` branches. All changes should be made to the `main` branch and then merged into `staging` and `production` via pull requests. This is especially important because changes pushed to `staging` and `production` branches will be automatically uploaded to the respective servers. + +### Commit strategy + +Wherever possible, a commit should represent a single completed change. We try to avoid `wip` commits in order to keep the commit history readable. + +In practice, though, we will often need to make incremental commits, particularly on feature and bugfix branches. The practice should be to squash all of the related commits into a single commit before merging the changes into `main`. + +### Naming Commits + +### Tagging Releases + +Whenever the KCWorks version number changes, it that commit should be tagged with the new version number. This can be done by running the following command: + +```shell +git tag -a -m "Release " +``` +We do not create branches for each numbered release. + +### Git Submodules + +KCWorks uses git submodules to manage dependencies. The submodules are located in the `site/kcworks/dependencies` folder. The submodules are cloned from the upstream repositories when the KCWorks instance is first created. They are updated from the upstream repositories when the KCWorks instance is updated. + +Note that in some cases there are inter-dependencies between these submodules. For example, the `invenio-record-importer-kcworks` submodule has its own dependency on the `invenio-group-collections-kcworks` submodule. When cloning the KCWorks repository, you **should not use the `--recurse-submodules` option** because this will clone redundant copies of these inter-dependent submodules. Instead, you should clone the KCWorks repository and then initialize the submodules in a separate step with `git submodule update --init`. Likewise, when updating the KCWorks submodules, you should use the `git submodule update --remote` command **without the `--recursive` option**. + + + +## Updating the running KCWorks instance with development changes + +### Changes to html template files + +Changes to html template files will be visible immediately in the running Knowledge Commons Works instance. You simply need to refresh the page in your browser. + +If you add a new template file (including overriding an existing template file), you will need to collect the new file into the central templates folder and restart the uwsgi processes. This can be done by running the following command inside the `web-ui` container: + +```shell +invenio collect -v +uwsgi --reload /tmp/uwsgi_ui.pid +``` +Then refresh your browser. + +### Changes to invenio.cfg + +Changes to the invenio.cfg file will only take effect after the instance uwsgi processes are restarted. This can be done by running the following command inside the `web-ui` container: +```shell +uwsgi --reload /tmp/uwsgi_ui.pid +``` +Or you can restart the docker-compose project, which will also restart the uwsgi processes. + +### Changes to theme (CSS) and javascript files + +#### The basic build process (slow) + +Invenio employs a build process for css and javascript files. Changes to these files will not be visible in the running Knowledge Commons Works instance until the build process is run. This can be done by running the following command inside the `web-ui` container: + +```shell +bash ./scripts/build-assets.sh +``` + +#### Rebuilding changed files on the fly (fast but limited) + +The problem is that this build process takes a long time to run, especially in the containers. For most tasks, you can instead run the following command to watch for changes to the files and automatically rebuild them: + +```shell +invenio webpack run start +``` + +The file watching will continue until you stop it with CTRL-C. It will continue to occupy the terminal window where you started it. This means that you can see it respond and begin integrating changed files when it finds them. You can also see there any error or warning output from the build process--very helpful for debugging. + +> [!Note] +> The watch command will only pick up changes to files that already existed during the last Webpack build. If you add +> - a new javascript file +> - a new css (less) file +> - a new node.js package requirement +> then you need to again run the basic (slow) build script to include it in the build process. +> After that you can run `invenio webpack run start` again to pick up changes on the fly. + +### Adding new node.js packages to be included + +Normally, the node.js packages to be included in a project are listed in that project's package.json file. In the case of InvenioRDM, the package.json file is created dynamically by InvenioRDM each time the build process runs. So you cannot directly modify the package.json file in your instance folder. Instead, you must add the package to the package.json file in the InvenioRDM module that requires it. Unless you are creating a new stand-alone extension, this will mean adding the package to the `webpack.py` file in the `knowledge-commons-works/sites/kcworks` folder. + +There you will find a `WebpackThemeBundle` object that defines your bundle of js and style files along with their dependencies. If I wanted to add the `geopattern` package to the project, I would add it to the `dependencies` dictionary in the `WebpackThemeBundle` object like this: + +```python + +theme = WebpackThemeBundle( + __name__, + "assets", + default="semantic-ui", + themes={ + "semantic-ui": dict( + entry={ + "custom_pdf_viewer_js": "./js/invenio_custom_pdf_viewer" + "/pdfjs.js", + }, + dependencies={ + "geopattern": "^1.2.3", + }, + aliases={ + /* ... */ + }, + ), + }, +) +``` + +If you add a new node.js package to the project, you will then need to run the build script inside the `web-ui` container to install it: + +```shell +bash ./scripts/build-assets.sh +``` + +### Changes to static files + +Changes to static files like images will require running the collect command to copy them to the central static folder. This can be done by running the following command inside the `web-ui` container: + +```shell +invenio collect -v +``` + +You will then need to restart the uwsgi processes or restart the docker-compose project as described above. + +### Changes to python code in the `site` folder + +Changes to python code in the `site` folder should (like changes to template files) take effect immediately in the running Knowledge Commons Works instance. You simply need to refresh the page in your browser. + +#### Adding new entry points + +Sometimes you will need to add new entry points to inform the Flask application about additional code you have provided. This is done via the `setup.py` file in the `site` folder. Once you have added the entry point declaration, you will need to re-install the `kcworks` package in the `kcworks-ui`, `kcworks-api`, and `kcworks-worker` container. This can be done by running the following command inside the each container: + +```shell +cd /opt/invenio/src/site +pip install -e . +uwsgi --reload /tmp/uwsgi_ui.pid +``` + +If you have added js, css, or static files along with the entry point code, you will also need to run the collect and webpack build commands as described above and restart the docker-compose project. + +Note that entry point changes may be overridden if you pull a more recent version of the kcworks docker image and restart the docker-compose project. Ultimately the entry point changes will have to be added to a new version of the kcworks docker image. + +### Changes to external python modules (including Invenio modules) + +Changes to other python modules (including Invenio modules) will require rebuilding the main kcworks container. Additions to the python requirements should be added to the `Pipfile` in the kcworks folder and committed to the Github repository. You should then request that the kcworks container be rebuilt with the additions. + +In the meantime, required python packages can be installed directly in the `kcworks-ui`, `kcworks-api`, and `kcworks-worker` containers. Enter each container and then install the required package pip (not pipenv): + +```shell +pip install +``` + +## Digging deeper + +What follows is a step-by-step walk through this process. + +> [!Note] +> These instructions do not support installation under Windows. Windows users should emulate a Linux environment using WSL2. + +## Updating an Instance with Upstream Changes + +If changes have been made to the upstream Knowledge Commons Works repository and the kcworks container, you will need to update your local instance to reflect those changes. This process involves pulling the changes from the upstream repository, pulling the latest version of the kcworks docker image, restarting the docker-compose project with recreated containers, and rebuilding the asset files. + +1. First, from the root knowledge-commons-works folder, pull the changes from the upstream git repository: + +```shell +git pull origin main +``` + +2. Then pull the latest version of the kcworks docker image: + +```shell +docker pull monotasker/kcworks:latest +``` + +3. Next, restart the docker-compose project with recreated containers: + +```shell +docker-compose --file docker-compose.yml stop +docker-compose --file docker-compose.yml up -d --build --force-recreate +``` + +4. Clean up leftover containers and images: + +```shell +docker system prune -a +``` + +> [!Caution] +> Make sure that you run this `prune` command *while the containers are running.* If you run it while the containers are stopped, you will delete the containers and images that you need to run the application, as well as volumes with stored data. + +6. Rebuild the asset files with the following command: + +```shell +docker exec -it kcworks-ui bash +bash ./scripts/build-assets.sh +``` + +7. Then refresh your browser to see the changes. + +## Running automated tests (NEEDS UPDATING) + +Automated tests (unit tests and integration tests) are run every time a commit is pushed to the knowledge-commons-works Github repo. You can (and should) also run the test suite locally. + +There are currently two distinct sets of tests that have to be run separately: python tests run using invenio's fixtures, and javascript tests run separately using jest. + +### Python tests + +The python test suite includes (a) unit tests for back end code, (b) tests of ui views and api requests run with a client fixture, (c) user interaction tests run with selenium webdriver. To run the unit tests and view/request tests, navigate to the root knowledge-commons-works folder and run +```console +pipenv run pytest +``` +By default the selenium browser interaction tests are not run. To include these, run pytest with the E2E environment variable set to "yes": +```console +pipenv run E2E=yes pytest +``` +Running the selenium tests also requires that you have the Selenium Client and Chrome Webdriver installed locally. + +### Javascript tests + +Pytest does not directly test custom javascript files or React components. In order to test these, navigate to the root knowledge-commons-works folder and run +```console +npm run test +``` +These tests are run using the jest test runner, configured in the packages.json file in the root knowledge-commons-works folder. + +Note that these tests run using a local npm configuration in the knowledge-commons-works folder. Any packages that are normally available to InvenioRDM must be added to the local package.json configuration and will be installed in the local node_modules folder. Since this folder is not included in GIT version control, before you run the javascript tests you must ensure the required packages are installed locally by running +```console +npm install +``` diff --git a/docs/source/in_depth.md b/docs/source/in_depth.md new file mode 100644 index 000000000..5662bfa20 --- /dev/null +++ b/docs/source/in_depth.md @@ -0,0 +1,348 @@ +# In-depth Installation Instructions (NEEDS UPDATING) + +## Install Python and Required Python Tools + +### Ensure some version of python is installed + +Most operating systems (especially MacOS and Linux) will already have a version of Python installed. You can proceed directly to the next step. + +### Install pyenv and pipenv + +First install the **pyenv** tool to manage python versions, and the **pipenv** tool to manage virtual environments. (There are other tools to use for virtual environment management, but InvenioRDM is built to work with pipenv.) + +Instructions for Linux, MacOS, and Windows can be found here: https://www.newline.co/courses/create-a-serverless-slackbot-with-aws-lambda-and-python/installing-python-3-and-pyenv-on-macos-windows-and-linux + +### Install and enable Python 3.9.16 + +Invenio's command line tools require a specific python version to work reliably. Currently this is python 3.9.16. At the command line, first install this python version using pyenv: +```console +pyenv install 3.9.16 +``` +Note: It is important to use cpython. Invenio does not support other python interpreters (like pypy) and advises against using anaconda python in particular for running the RDM application. + +Just because this python version is installed does not guarantee it will be used. Next, navigate to the directory where you cloned the source code, and set the correct python version to be used locally: + +```console +cd ~/path/to/directory/knowledge-commons-works +pyenv local 3.9.16 +``` + +#### Install the invenio-cli command line tool + +From the same directory Use pip to install the **invenio-cli** python package. (Do not use pipenv yet or create a virtual environment.) + +```console +pip install invenio-cli +``` + +## Install Docker 20.10.10+ and Docker-compose 1.17.0+ + +### Linux + +If you are using Ubuntu Linux, follow the steps for installing Docker and Docker-compose explained here: https://linux.how2shout.com/install-and-configure-docker-compose-on-ubuntu-22-04-lts-jammy/ + +You must then create a `docker` group and add the current user to it (so that you can run docker commands without sudo). This is *required* for the invenio-cli scripts to work, and it must be done for the *same user* that will run the cli commands: + +```console +sudo usermod --append --groups docker $USER +``` + +You will likely want to configure Docker to start on system boot with systemd. + +### MacOS + +If you are using MacOS, follow the steps for installing Docker desktop explained here: https://docs.docker.com/desktop/install/mac-install/ + +You will then need to ensure Docker has enough memory to run all the InvenioRDM containers. In the Docker Desktop app, + +- click settings cog icon (top bar near right) +- set the memory slider under the "Resources" tab manually to at least 6-8GB + +Note: The environment variable recommended in the InvenioRDM documentation for MacOS 11 Big Sur is *not* necessary for newer MacOS versions. + +### Fixing docker-compose "not found" error + +With the release of compose v2, the command syntax changed from `docker-compose` to `docker compose` (a command followed by a sub-command instead of one hyphenated command). This will break the invenio-cli scripts, which use the `docker-compose` command and you will receive an error asking you to install the "docker-compose" package. + +One solution on Linux systems is to install Docker Compose standalone, which uses the old `docker-compose` syntax: + +```console +sudo curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose +``` + +Another approach is simply to alias the `docker compose` command to `docker-compose` in the configuration file for your command line shell (.bashrc, .zshrc, or whichever config file is used by your shell). + +See further https://docs.docker.com/compose/install/other/ + +### Docker log rotation + +Regardless of your operating system, you should set up log rotation for containers to keep the size of logging files from getting out of control. Either set your default logging driver to "local" (which rotates log files automatically) or set logging configuration if you use the "json-file" logging driver. See https://docs.docker.com/config/containers/logging/configure/ + +### Note about docker contexts + +Make sure to always use the same Docker context to run all of the containers for InvenioRDM. See further, https://docs.docker.com/engine/context/working-with-contexts/ + +## Install Node.js and NVM + +Currently InvenioRDM (v. 11) requires Node.js version 16.19.1. The best way to install and manage Node.js versions is using the nvm version manager. You can find instructions here: https://www.freecodecamp.org/news/node-version-manager-nvm-install-guide/ + +Once nvm is installed, install the required Node.js version and set it as the active version: +```console +nvm install v16.19.1 +nvm use 16.19.1 +``` +You may have other Node versions installed as well, so before a session working with Knowledge Commons Works it's a good idea to make sure you're using the correct version. On MacOS and Linux you can check +from the command line with +```console +which node +``` + +## Clone the knowledge-commons-works Code + +Using GIT, clone this repository. You should then have a folder called `knowledge-commons-works` (unless you chose to name it something else) on your local computer. + +(add-and-configure-an-environment-file)= +## Add and Configure an Environment File + +### Standardized environment variables + +This file must include the following variables with these values: + +``` +INVENIO_INSTANCE_PATH=/opt/invenio/var/instance +INVENIO_RECORD_IMPORTER_LOCAL_DATA_DIR=/ +INVENIO_RECORD_IMPORTER_DATA_DIR=/opt/invenio/var/import_data +INVENIO_SEARCH_DOMAIN='search:9200' +INVENIO_SITE_UI_URL="https://localhost" +INVENIO_SITE_API_URL="https://localhost/api" +REDIS_DOMAIN='cache:6379' +INVENIO_SQLALCHEMY_DATABASE_URI="postgresql+psycopg2://kcworks:kcworks@db/kcworks" +POSTGRES_USER=kcworks +POSTGRES_DB=kcworks +``` + +The INVENIO_INSTANCE_PATH should be set to the full path of the instance directory where InvenioRDM will store its compiled files. Since KC Works runs inside containers, this is normally a standard folder inside the container file systems (/opt/invenio/var/instance). If you were to run InvenioRDM with the python/uwsgi processes installed on your local machine, this would be a folder inside your local virtual environment folder. For example, on MacOS this might be ~/.local/share/virtualenvs/{virtual env name}/var/instance/. + +### Variables for local credentials + +Several variables hold random values used to secure the application, or hold passwords and email addresses supplied by the local developer: + +``` +INVENIO_CSRF_SECRET_SALT='..put a long random value here..' +INVENIO_SECURITY_LOGIN_SALT='..put a long random value here..' +INVENIO_SECRET_KEY=CHANGE_ME +POSTGRES_PASSWORD=??? +PGADMIN_DEFAULT_EMAIL=??? +PGADMIN_DEFAULT_PASSWORD=??? +``` + +Random values for secrets like INVENIO_SECRET_KEY can be generated in a terminal by running +```console +python -c 'import secrets; print(secrets.token_hex())' +``` +#### Additional environment variables with sensitive information + +Additionally, you should add the following variables with the appropriate values obtained from the Commons administrators: + +``` +COMMONS_API_TOKEN=mytoken # this must be obtained from the Commons administrators +COMMONS_SEARCH_API_TOKEN=mytoken # this must be obtained from the Commons administrators +INVENIO_DATACITE_PASSWORD=myinveniodatacitepassword # this must be obtained from the Commons administrators +``` +You will also need to enter the following variable with a dummy value and then replace it with the actual value after the instance is set up. Once you have an administrative user, you can generate a token for that user in the KC Works admin ui and enter it here: + +``` +API_TOKEN=myapitoken +``` + +#### Additional required environment variables with paths on your local file system + +The next variables refer to paths on your local file system that are used during local development to provide easy access to the source code of various python packages and KCWorks modules: + +``` +PYTHON_LOCAL_GIT_PACKAGES_PATH=/path/to/local/git/packages +PYTHON_LOCAL_SITE_PACKAGES_PATH=/path/to/local/virtual/environment/lib/python3.12/site-packages +``` + +PYTHON_LOCAL_GIT_PACKAGES_PATH is the parent directory that holds cloned packages that aren't available via pip or that have been forked by us. If you are not working with the KCWorks custom modules locally, this can be set to the folder where you cloned the KCWorks code. Otherwise, it should be the path to the parent folder containing the git repositories for the forked Invenio modules and the extra KC Works modules. + +PYTHON_LOCAL_SITE_PACKAGES_PATH is the path to the site-packages folder in your local virtual environment. This assumes that you have run `pipenv install --dev --python=3.12` in your KCWorks project folder to install the python packages locally in a virtual environment. + +## Install the Invenio Python Modules + +Navigate to the root knowledge-commons-works folder and run +```console +pipenv install --dev --python=3.12 +``` +Note: This installation step will take several minutes. + +This stage +- creates and initializes a Python virtual environment using pipenv +- locks the python package requirements +- installs the Invenio python packages (with pipenv) + - these packages are again installed under your virtual environment folder. On MacOS this is often ~/.local/share/virtualenvs/{virtual env name}/lib/python3.9/site-packages/. You will find several modules installed here with names that start with "invenio_". +- installs the `kcworks` Python package (with pipenv) + - alongside the Invenio packages you will also find a `kcworks` package containing any custom extensions to InvenioRDM defined in your `knowledge-commons-works/sites/` folder +- installs required python dependencies (with pipenv) + +## Build and Configure the Containerized Services + +### Build and start the containers + +Make sure you are in the root knowledge-commons-works folder and then run +```console +docker-compose up -d +``` +This step will +- build the docker image for the nginx web server (frontend) using ./docker/nginx/Dockerfile +- pull remote images for other services: mq, search, db, cache, pgadmin, opensearch-dashboards +- start containers from all of these images and mounts local files or folders into the containers as required in the docker-compose.yml and docker-services.yml files + +### Create and initialize the database, search indices, and task queue + +Again, from the root knowledge-commons-works folder, run this command: +```console +invenio-cli services setup +``` + +This step will +- create the postgresql database and table structure +- create Invenio admin role and assigns it superuser access +- begin indexing with OpenSearch +- create Invenio fixtures +- insert demo data into the database (unless you add the --no-demo-data flag) + +Note: If for some reason you need to run this step again, you will need to add the `--force` flag to the `docker-compose` command. This tells Invenio to destroy any existing redis cache, database, index, and task queue before recreating them all. Just be aware that performing this setup again with `--force` will **destroy all data in your database and all OpenSearch indices**. + +### Start the uwsgi applications and celery worker + +Finally, you need to start the actual applications. Knowledge Commons Works is actually run as two separate applications: one providing an html user interface, and one providing a REST api and serving JSON responses. Each application is served to the nginx web server by its own uwsgi process. The nginx server begins automatically when the `frontend` docker container starts, but the uwsgi applications run on your local machine and need to be started directly. + +These applications are also supported by a Celery worker process. This is a task queue that (with the help of the RabbitMQ docker container) frees up the python applications from being blocked by long-running tasks like indexing. The celery worker also runs on your local machine and must be started directly. + +If you want to quickly start all of these processes in the background (as daemons), you can run the kcr-startup.sh script in the root knowledge-commons-works directory: +```console +bash kcr-startup.sh +``` +The processes will output request and error logging to files in the `logs` folder of your knowledge-commons-works folder. + +To stop these processes, simply run +```console +bash kcr-shutdown.sh +``` + +If you would like to view the real time log output of these processes, you can also start them individually in three separate terminals: +```console +pipenv run celery --app invenio_app.celery worker --beat --events --loglevel INFO +``` +```console +pipenv run uwsgi docker/uwsgi/uwsgi_ui.ini --pidfile=/tmp/kcr_ui.pid +``` +```console +pipenv run uwsgi docker/uwsgi/uwsgi_rest.ini --pidfile=/tmp/kcr_api.pid +``` +These processes can be stopped individually by pressing CTRL-C + +### Create an admin user + +From the command line, run these commands to create and activate the admin user: +```console +pipenv run invenio users create --password +pipenv run invenio users activate +``` +If you want this user to have access to the administration panel in Invenio, you also need to run +```console +pipenv run invenio access allow administration-access user +``` + +## Use the application! + +You should now be able to access the following: +- The Knowledge Commons Works app (https://localhost) +- The Knowledge Commons Works REST api (https://localhost/api) +- pgAdmin for database management (https://localhost/pgadmin) +- Opensearch Dashboards for managing search (https://localhost:5601) + +### Controlling the Application Services + +Once Knowledge Commons Works is installed, you can manage its services from the command line. **Note: Unless otherwise specified, the commands below must be run from the root knowledge-commons-works folder.** + +### Startup and shutdown scripts + +The bash script kcr-startup.sh will start + - the containerized services (if not running) + - the celery worker + - the two uwsgi processes +It will also ensure that you have a .env file and copy your set your INVENIO_INSTANCE_PATH variable in that file to your local instance folder, matching the instance_path variable in your .invenio.private file. + +Simply navigate to the root knowledge-commons-works folder and run +```console +bash ./kcr-startup.sh +``` + +To stop the processes and containerized services, simply run +```console +bash ./kcr-shutdown.sh +``` + +### Controlling just the containerized services + +If you want to stop or start just the containerized services (rather than the local processes), you can use the invenio cli: +```console +invenio-cli services start +invenio-cli services stop +``` +Or you can control them directly with the docker-compose command: +```console +docker-compose up -d +docker-compose stop +``` +Note that stopping the containers this way will not destroy the data and configuration which live in docker volumes. Those volumes persist as long as the containers are not destroyed. **Do not use the `docker-compose down` command unless you want the containers to be destroyed.** + +### View logging output for uwsgi processes + +Activity and error logging for the two uwsgi processes are written to date-stamped files in the knowledge-commons-works/logs/ folder. To watch the live logging output from one of these processes, open a new terminal in your knowledge-commons-works folder and run +```console +tail -f logs/uwsgi-ui-{date}.log +``` +or +```console +tail -f logs/uwsgi-api-{date}.log +``` + +### View container logging output + +The logging output (and stdout) can be viewed with Docker Desktop using its convenient ui. It can also be viewed from the command line using: + +```console +docker logs -f +``` + +The names of the various images are: +- nginx: kcworks-frontend-1 +- RabbitMQ: kcworks-mq-1 +- PostgreSQL: kcworks-db-1 +- OpenSearch: kcworks-search-1 +- Redis: kcworks-cache-1 +- OpenSearch Dashboards: kcworks-opensearch-dashboards-1 +- pgAdmin: kcworks-pgadmin-1 + +### Controlling containerized nginx server + +The frontend container is configured so that the configuration files in docker/nginx/ are bind mounted. This means that changes to those config files can be seen in the running container and enabled without rebuilding the container. To reload the nginx configuration, first **enter the frontend container**: +```console +docker exec -it kcworks-frontend-1 bash +``` +Then tell gninx to reload the config files: +```console +nginx -s reload +``` +You can also test the nginx config prior to reloading by running +```console +nginx -t +``` +Alternately, you can rebuild and restart the frontend container by running +```console +docker-compose up -d --build frontend +``` diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 000000000..5df881c7c --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,30 @@ +.. Knowledge Commons Works documentation master file, created by + sphinx-quickstart on Mon Jan 6 17:53:27 2025. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to the Knowledge Commons Works technical documentation! +=============================================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + README + changelog + installation + metadata + customizations + configuration + cli_commands + infrastructure + developing + in_depth + reference + +.. Indices and tables +.. ================== + +.. * :ref:`genindex` +.. * :ref:`modindex` +.. * :ref:`search` diff --git a/docs/source/infrastructure.md b/docs/source/infrastructure.md new file mode 100644 index 000000000..f598357a1 --- /dev/null +++ b/docs/source/infrastructure.md @@ -0,0 +1 @@ +# KCWorks Infrastructure diff --git a/docs/source/installation.md b/docs/source/installation.md new file mode 100644 index 000000000..5dbeb497d --- /dev/null +++ b/docs/source/installation.md @@ -0,0 +1,121 @@ +# Installation + +## Quickstart + +These instructions allow you to run Knowledge Commons Works for local development. The app source files are copied onto your system, but the Flask application and other services (database, search, etc.) are run in Docker containers. The application is served to your browser by an nginx web server running in a separate container. + +First you will need to have the correct versions of Docker (20.10.10+ with Docker Compose 1.17.0+) and Python (3.12.0+ with pipenv). + +From there, installation involves these steps. Each one is further explained below, but here is a quick reference: + +### 1. Clone the git repository + +- From your command line, navigate to the parent folder where you want the cloned repository code to live +- Clone the knowledge-commons-works repository with `git clone git@github.com:MESH-Research/knowledge-commons-works.git && git submodule update --init` + +> **Note**: Do not use the `--recurse-submodules` option when cloning the repository or the `--recursive` option when initializing the submodules. This will clone redundant copies of the inter-dependent submodules. + +### 2. Create your configuration files + +- `cd knowledge-commons-works` +- Create and configure the `.env` file in this folder as described {ref}`here ` +- Create the `.invenio.private` file with the following contents: + +```shell +[cli] +services_setup = True +instance_path = /opt/invenio/var/instance +``` +### 3. Start the docker-compose project + +- `docker-compose --file docker-compose.yml up -d` + +### 4. Initialize the database and other services, and build asset files + +- enter the `web-ui` container by running `docker exec -it kcworks-ui bash` + +> **Note**: The container name may be different depending on your local docker setup. You can find the correct name by running `docker ps` + +- run the script to set up the instance services and build static assets `bash ./scripts/setup-services.sh` + +> **Note**: Some of the commands in this script may take a while to run. Patience is required! The `invenio rdm-records fixtures` command in particular may take up to an hour to complete during which time it provides no feedback. Don't despair! It is working. + +### 5. Create your own admin user + +- enter the `web-ui` container by running `docker exec -it kcworks-ui bash` + +> **Note**: The container name may be different depending on your local docker setup. You can find the correct name by running `docker ps` + +- run the commands: + +```shell +invenio users create --password +invenio users activate +invenio access allow administration-access user +``` + +### 6. View the application + +- The Knowledge Commons Works app is now running at `https://localhost` +- The REST API is running at `https://localhost/api` +- pgAdmin is running at `https://localhost/pgadmin` +- OpenSearch Dashboards is running at `https://localhost:5601` + +This setup will allow you to make changes to the core Knowledge Commons Works codebase and see those changes reflected in the running application. + +## Full local development setup + +You will need to take some further steps if you want to + - Make and test changes to the various invenio modules that are included as git submodules. + - View and insert debugging statements into the code of the various core Invenio packages installed into the python environment. +To do this, you will need to do the following: + +1. Ensure the required git submodules are cloned by running the following commands in the `knowledge-commons-works` folder: + ```shell + git submodule update --init + ``` + This will clone the following repositories: + ```shell + main git@github.com:MESH-Research/invenio-record-importer-kcworks.git + main git@github.com:MESH-Research/invenio-group-collections-kcworks.git + main git@github.com:MESH-Research/invenio-modular-deposit-form.git + main git@github.com:MESH-Research/invenio-modular-detail-page.git + main git@github.com:MESH-Research/invenio-remote-api-provisioner.git + main git@github.com:MESH-Research/invenio-remote-user-data-kcworks.git + local-working git@github.com:MESH-Research/invenio-communities.git + local-working git@github.com:MESH-Research/invenio-rdm-records.git + local-working git@github.com:MESH-Research/invenio-records-resources.git + local-working git@github.com:MESH-Research/invenio-vocabularies.git + ``` + These cloned repositories should then appear under the `knowledge-commons-works/site/kcworks/dependencies` folder. +2. Install the python packages required by Knowldge Commons Works locally by running `pipenv install` in the `knowledge-commons-works` folder. +3. When you start up the docker compose project, add an additional project file to the command: + - `docker-compose --file docker-compose.yml --file docker-compose.dev.yml up -d` +This will mount a variety of local package folders as bind mounts in your running containers. This will allow you to make changes to the python code in the cloned repositories and see those changes reflected in the running Knowledge Commons Works instance. + +## Controlling the KCWorks (Flask) application + +The application instance and its services can be started and stopped by starting and stopping the docker-compose project: + +```shell +docker-compose --file docker-compose.yml up -d +``` +```shell +docker-compose --file docker-compose.yml stop +``` + +> [!Caution] +> Do not use the `docker-compose down` command unless you want the containers to be destroyed. This will destroy all data in your database and all OpenSearch indices. YOU DO NOT WANT TO DO THIS! + +If you need to restart the main Flask application (e.g., after making configuration changes) you can do so either by stopping and restarting the docker-compose project or by running the following command inside the `kcworks-ui` container: + +```shell +uwsgi --reload /tmp/uwsgi_ui.pid +``` + +Similarly, the REST API can be restarted by running the following command inside the `web-ui` container: + +```shell +uwsgi --reload /tmp/uwsgi_api.pid +``` +But these commands should not be necessary in normal operation. diff --git a/docs/source/metadata.md b/docs/source/metadata.md new file mode 100644 index 000000000..f79aa64de --- /dev/null +++ b/docs/source/metadata.md @@ -0,0 +1,880 @@ +# Metadata Schema, Vocabularies, and Identifiers + +The default metadata schema for InvenioRDM records is defined in the `invenio-rdm-records` package and documented [here](https://inveniordm.docs.cern.ch/reference/metadata/). It also includes a number of optional metadata fields which have been enabled in KCWorks, documented [here](https://inveniordm.docs.cern.ch/reference/metadata/optional_metadata/). + +Beyond these InvenioRDM fields, KCWorks adds a number of custom metadata fields to the schema using InvenioRDM's custom field mechanism. These are all located in the top-level `custom_fields` field of the record metadata. They are prefixed with two different namespaces: + +- `kcr`: custom fields that are used to store data from the KC system. These fields **may** be used for new data, but are not required. +- `hclegacy`: custom fields that are used to store data from the legacy CORE repository. These fields **must not** be used for new data. + +## Example metadata record + +### JSON object for record creation + +What follows is an example of a complete metadata record (JSON object) used to create a KCWorks record. The various fields and their possible values are described in the sections below. + +Note that no single actual record would include all of these fields. The example is provided to illustrate the structure of the metadata record and the sort of values that are valid for each field. + +```json +{ + "custom_fields": { + "code:codeRepository": "https://github.com/my-project", + "code:programmingLanguage": ["Python", "JavaScript"], + "code:developmentStatus": "active", + "journal:journal": { + "title": "My Journal Title", + "issue": "2", + "volume": "8", + "pages": "123-456", + "issn": "0378-5955" + }, + "imprint:imprint": { + "title": "My Book Title", + "pages": "458", + "isbn": "0-06-251587-X", + "place": "Lagos" + }, + "meeting:meeting": { + "dates": "October 2022", + "place": "Michigan State University", + "title": "Fall 2022 Meeting of the Humanities Commons Working Group", + "acronym": "MET", + "url": "https://myevent.org" + }, + "kcr:ai_usage": { + "ai_used": true, + "ai_description": "I used ChatGPT to generate the references." + }, + "kcr:book_series": [ + { + "series_title": "My series", + "series_volume": "8" + } + ], + "kcr:commons_domain": "hcommons.org", + "kcr:course_title": "My course", + "kcr:degree": "PhD", + "kcr:discipline": "Education", + "kcr:edition": "2nd", + "kcr:institution_department": "Education", + "kcr:media": [ + "printed paper" + ], + "kcr:meeting_organization": "Humanities Commons", + "kcr:notes": "These are some notes about the deposit not intended for the public record.", + "kcr:project_title": "My project", + "kcr:publication_url": "https://mycourse.org", + "kcr:sponsoring_institution": "MSU", + "kcr:submitter_email": "jane.doe@hcommons.org", + "kcr:submitter_username": "janedoe", + "kcr:volumes": { + "total_volumes": "8", + "volume": "1" + }, + "kcr:user_defined_tags": [ + "Access", + "Digital humanities", + "Collaboration" + ] + }, + "metadata": { + "resource_type": { + "id": "instructionalResource-syllabus" + }, + "creators": [ + { + "person_or_org": { + "name": "Doe, Jane", + "type": "personal", + "given_name": "Jane", + "family_name": "Doe", + "identifiers": [ + { + "scheme": "orcid", + "identifier": "0000-0001-2345-6789" + } + ] + }, + "role": { + "id": "author" + }, + "affiliations": [{"name": "Michigan State University"}] + } + ], + "title": "A Syllabus for a Digital Pedagogy Course", + "additional_titles": [ + { + "title": "Teaching in the Age of AI", + "type": { "id": "subtitle" }, + "lang": { "id": "eng" } + } + ], + "publisher": "KCWorks", + "publication_date": "2018/2020-09", + "subjects": [ + { + "id": "http://id.worldcat.org/fast/958235", + "subject": "History", + "scheme": "FAST-topical" + }, + { + "id": "http://id.worldcat.org/fast/1086436", + "subject": "Race", + "scheme": "FAST-topical" + }, + { + "id": "http://id.worldcat.org/fast/966892", + "subject": "Identity (Psychology)", + "scheme": "FAST-topical" + } + ], + "contributors": [ + { + "person_or_org": { + "name": "John Doe", + "type": "personal", + "given_name": "John", + "family_name": "Doe", + "identifiers": [ + { + "scheme": "orcid", + "identifier": "0000-0001-2345-6780" + } + ] + }, + "role": { "id": "other" }, + "affiliations": [{"name": "Michigan State University"}] + } + ], + "dates": [ + { + "date": "2025-01-01", + "type": { "id": "other" }, + "description": "The date when the syllabus was made available." + } + ], + "formats": [ + "application/pdf" + ], + "languages": [ + { "id": "eng" } + ], + "identifiers": [ + { + "identifier": "https://example.com/syllabus", + "scheme": "url" + } + ], + "related_identifiers": [ + { + "identifier": "10.1234/foo.bar", + "scheme": "doi", + "relation_type": { "id": "iscitedby" }, + "resource_type": { "id": "dataset" } + } + ], + "sizes": [ + "11 pages", + "32 x 24 cm" + ], + "version": "v1.0", + "rights": [ + { + "id": "cc-by-nc-4.0", + "description": { + "en": "Allows re-distribution and re-use of a licensed work on the condition that the creator is appropriately credited and that the re-use is not for commercial purposes." + }, + "link": "https://creativecommons.org/licenses/by-nc/4.0/legalcode" + } + ], + "description": "

A description

with HTML tags

", + "additional_descriptions": [ + { + "description": "Some additional description about the methods involved in the syllabus.", + "type": { + "id": "methods", + "title": { + "de": "Technische Informationen", + "en": "Technical info" + } + }, + "lang": {"id": "eng", "title": {"en": "English"}} + } + ], + "locations": { + "features": [ + { + "geometry": { + "type": "Point", + "coordinates": [-32.94682, -60.63932] + }, + "place": "test location place", + "description": "test location description", + "identifiers": [ + {"identifier": "12345abcde", "scheme": "wikidata"}, + {"identifier": "12345abcde", "scheme": "geonames"} + ] + } + ] + }, + "funding": [ + { + "funder": { + "id": "00k4n6c32", + }, + "award": { + "identifiers": [ + { + "identifier": "https://sandbox.zenodo.org/", + "scheme": "url" + } + ], + "number": "111023", + "title": { + "en": "Launching of the research program on meaning processing" + } + } + } + ], + }, + "access": { + "record": "public", + "files": "restricted", + "embargo": { + "active": true, + "until": "2029-01-01", + "reason": "Publisher requires embargo.", + } + }, +} +``` + +### JSON object retrieved from the record API + +The JSON object retrieved from the record API shares the same basic structure as the JSON object used to create the record, except that it includes a number of additional fields. Some properties are also filled out with additional details (e.g., readable titles for licenses, etc.) + +## Controlled Vocabularies + +### Subject headings + +#### FAST + +The FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) is used for the `subjects` field. See the [metadata.subjects](#metadata.subjects) section for more information about how to include FAST subjects in a KCWorks record. + +#### Homosaurus + +The FAST vocabulary is augmented in KCWorks by the Homosaurus vocabulary (https://homosaurus.org/) for subjects related to sexuality and gender identity. See the [metadata.subjects](#metadata.subjects) section for information about how to include Homosaurus subjects in a KCWorks record. + +#### Resource types + +#### Creator/contributor roles + +## Identifier Schemes + +### Works + +#### DOI (primary identifier) + +KCWorks (and InvenioRDM) supports the DOI identifier scheme to identify works in the repository. Note that two DOIs are minted for each KCWorks record: one for the current version of the record, and one for the work as a whole (including all versions). The version-specific DOI is stored in the `pids` property of the metadata record (`pids.identifiers.doi`). The work DOI is stored in the `parent.pids.doi` property of the `parent` object. + +These DOIs are minted by DataCite (https://datacite.org/) and the attached metadata is maintained automatically by KCWorks. + +Additional DOIs minted elsewhere can be attached to a KCWorks record. If provided at record creation such external DOIs can be used as the record's primary identifier (in `pids.doi`). Otherwise, they can be added using the `identifiers` property of the metadata record using the scheme `alternate-doi`. In both cases, these externally minted DOIs are **not** maintained automatically by KCWorks. + +#### OAI (secondary identifier) + +KCWorks also supports the OAI identifier scheme. The OAI identifier for a KCWorks record is stored in the `pids` property of the metadata record (`pids.identifiers.oai`). + +#### Handle (secondary identifier) + +KCWorks also supports the Handle identifier scheme (https://handle.net/). The Handle identifier for a KCWorks record is stored in the `identifiers` property of the metadata record (`identifiers[0].identifier`) using the scheme `handle`. + +#### ISSN (secondary identifier) + +#### ISBN (secondary identifier) + +### People + +#### ORCID (recommended) + +KCWorks (and InvenioRDM) supports the ORCID identifier scheme. The ORCID of the submitter of the KCWorks record is stored in the `person_or_org.identifiers` property of the `creators` array (`creators[0].person_or_org.identifiers.identifier`). A KCWorks user's ORCID id is also drawn from their KC profile (if they have provided one) and stored in their system user profile (as `.user_profile.identifier_orcid`). + +For details on how to use ORCID identifiers in KCWorks, see the section on [Metadata.creators](#metadata.creators) below. + +#### KC Username (recommended) + +KCWorks also allows the use of Knowledge Commons usernames as identifiers. The KC username of the submitter of the KCWorks record is stored in the `person_or_org.identifiers` property of the `creators` array (`creators[0].person_or_org.identifiers.identifier`) using the scheme `kc_username`. + +For details on how to use KC usernames in KCWorks, see the section on [Metadata.creators](#metadata.creators) below. + +#### GND + +KCWorks also supports the Integrated Authority File (GND) identifier scheme (https://www.dnb.de/EN/Professionell/Standardisierung/GND/gnd_node.html). The GND identifier of the submitter of the KCWorks record is stored in the `person_or_org.identifiers` property of the `creators` array (`creators[0].person_or_org.identifiers.identifier`) using the scheme `gnd`. + +#### ISNI + +KCWorks also supports the ISNI identifier scheme (https://isni.org/). The ISNI of the submitter of the KCWorks record is stored in the `person_or_org.identifiers` property of the `creators` array (`creators[0].person_or_org.identifiers.identifier`) using the scheme `isni`. + +### Organizations + +#### ROR (recommended) + +Organization identifiers can appear in the `creators` and `contributors` arrays, either for organizational creators/contributors or in the `affiliations` array of a personal creator/contributor. These fields *may* identify an organization using its id in Research Organization Registry (https://ror.org/) using the scheme `ror`, although free text names are also supported. + +#### Grid (deprecated) + +KCWorks also supports the Grid identifier scheme (https://www.grid.ac/) for organizations using the scheme `grid`. This scheme is deprecated in favour of ROR, however, and should not be used for new identifiers. + +#### GND + +KCWorks also supports the Integrated Authority File (GND) identifier scheme (https://www.dnb.de/EN/Professionell/Standardisierung/GND/gnd_node.html) for organizations using the scheme `gnd`. + +### Funders + +#### DOI + +Funders in the `metadata.funding` array can be identified using DOIs formed with a FundRef id and the scheme `doi`. + +#### OFR + +Funders in the `metadata.funding` array can also be identified using the Open Funder Registry (https://openfunder.org/) identifiers and the scheme `ofr`. + +## KCWorks Implementation of Core InvenioRDM Fields + +### metadata.subjects + +Note that KCWorks employs the FAST controlled vocabulary (https://www.oclc.org/research/areas/data-science/fast.html) for the `subjects` field, complemented by the Homosaurus vocabulary (https://homosaurus.org/). + +The FAST vocabulary is divided into a number of sub-vocabularies called "facets", allowing more efficient searching and less ambiguity in the subject headings. FAST subjects in the `metadata.subjects` array must include the complete WorldCat url for the subject heading, the standard human-readable label, and a `scheme` including "FAST" followed by a hyphen and the FAST facet name in lowercase: i.e., one of +- "FAST-topical" +- "FAST-geographic" +- "FAST-corporate" +- "FAST-formgenre" +- "FAST-event" +- "FAST-meeting" +- "FAST-personal" +- "FAST-title" +- "FAST-chronological" + +You can search the FAST subject headings and their corresponding WorldCat urls [here](https://fast.oclc.org/searchfast). The OCLC also provides helpful tools such as assignFAST, which suggests FAST subject headings based on a string (https://fast.oclc.org/assignfast/) and a converter from LCSH subject headings to FAST subject (http://fast.oclc.org/lcsh2fast). + +Subject from the Homosaurus vocabulary must similarly include the complete homosaurus.org url as the `id`, the standard human-readable label as the `subject`, and a `scheme` with the value "Homosaurus". The Homosaurus subject headings can be searched [here](https://homosaurus.org/search/v3). + +Example: +```json +{ + "subjects": [ + { + "id": "http://id.worldcat.org/fast/123456", + "subject": "Art History", + "scheme": "FAST-topical" + }, + { + "id": "https://homosaurus.org/v3/homoit0000669", + "subject": "Intersex variations", + "scheme": "Homosaurus" + } + ] +} +``` + +### metadata.creators/metadata.contributors + +Note that the KC username of a creator or contributor may be stored in the `person_or_org.identifiers` array of the creator or contributor object with the scheme `kc_username`. + +Users are also strongly encouraged to include an ORCID identifier in the `person_or_org.identifiers` array with the scheme `orcid`. + +> [!Note] +> The KC username is the primary link between a KCWorks record and a KC user. If you want a work to be associated with a KC user, you must include the KC username in creator or contributor object. + +Example: +```json +{ + "person_or_org": { + "identifiers": [ + { + "scheme": "kc_username", + "identifier": "jdoe" + }, + { + "scheme": "orcid", + "identifier": "0000-0000-0000-0000" + } + ] + } +} +``` + +## KCWorks Custom Fields (kcworks/site/metadata_fields) + +### kcr:ai_usage + +Type: `Object[boolean, string]` + +This field stores data about any use of generative AI in the production of the record. + +Example: +```json +{ + "kcr:ai_usage": { + "ai_used": true, + "ai_description": "This paper was edited using generative AI editing software." + } +} +``` + +### kcr:media + +Type: `Array[string]` + +This field stores a list of media or materials involved in the creation of the record. This field is used to store free-form user-defined descriptors of the media or materials and does not impose any controlled vocabulary. + +Example: +```json +{ + "kcr:media": ["watercolor", "found objects", "audio recordings"] +} +``` + +### kcr:commons_domain + +Type: `string` + +This field stores the KC organizational (Commons) domain associated with the KCWorks record, if any. The record should also be placed in the KCWorks collection associated with this organization. + +Example: +```json +{ + "kcr:commons_domain": "arlisna.hcommons.org" +} +``` + +### kcr:chapter_label + +Type: `string` + +This field stores the label of the chapter associated with the KCWorks record, if any. This allows us to differentiate between a simple chapter label (e.g. "Chapter 1") and a more substantive title for the same chapter (e.g., "The Role of AI in Modern Art"). + +Example: +```json +{ + "kcr:chapter_label": "Chapter 1" +} +``` + +### kcr:content_warning + +Type: `string` + +This field stores an optional content warning for the KCWorks record. This is used to flag the record for KCWorks users so that they can be aware of potentially problematic content in the record. **This field is not to be used for content moderation by KCWorks moderators or admins. It is only to be used voluntarily and as desired by the record submitter.** + +Example: +```json +{ + "kcr:content_warning": "This work contains detailed accounts of abuse that may be distressing to some readers." +} +``` + +### kcr:course_title + +Type: `string` + +This field stores the title of the course associated with the KCWorks record. It is intended primarily for use with syllabi and instructional materials. + +Example: +```json +{ + "kcr:course_title": "Introduction to Modern Art" +} +``` + +### kcr:degree + +Type: `string` + +This field stores the educational degree (e.g., PhD, DPhil, MA, etc.) associated with the KCWorks record. It is intended primarily for use with theses and dissertations. + +Example: +```json +{ + "kcr:degree": "PhD" +} +``` + +### kcr:discipline + +Type: `string` + +This field stores the academic discipline associated with the KCWorks record. It is intended primarily for use with theses, dissertations, and other educational artifacts. It is not intended as a general-purpose field for describing the subject matter of the KCWorks record. For that, you should use the `metadata.subjects` and `kcr:user_defined_tags` fields. + +This field is intended to complement the `thesis:university` and `kcr:institution_department` fields. + +This field is not constrained by any controlled vocabulary. + +Example: +```json +{ + "kcr:discipline": "Latin American Literature" +} +``` + +### kcr:edition + +Type: `string` + +This field stores a descriptor for the edition of the KCWorks record, if any. + +Example: +```json +{ + "kcr:edition": "Second Edition" +} +``` + +### kcr:meeting_organization + +Type: `string` + +This field stores the name of the organization associated with the meeting or conference associated with the KCWorks record. It is intended primarily for use with conference papers, presentations, proceedings, etc. + +Example: +```json +{ + "kcr:meeting_organization": "American Association of Art Historians" +} +``` + +### kcr:project_title + +Type: `string` + +This field stores the title of a project for which the KCWorks record was created. It can be used flexibly for, e.g., grant-funded projects, research projects, artistic projects, etc. + +Example: +```json +{ + "kcr:project_title": "Kingston Poetry Residency, 2024" +} +``` + +### kcr:publication_url + +Type: `string` (URL) + +This field stores the URL of the publication associated with the KCWorks record. It is *not* the URL of the KCWorks record itself or of the work it contains. For example, if the KCWorks record contains a journal article, it would *not* hold the URL for the published journal article. It is intended to hold the URL of the publication *as a whole* that the KCWorks record is based on or is a part of. So it might hold the main URL for the journal in which the article was published, or the main URL for the book in which the chapter was published, etc. + +This string must be a valid URL. + +Example: +```json +{ + "kcr:publication_url": "https://www.example.com/publication/123456" +} +``` + +### kcr:sponsoring_institution + +Type: `string` + +This field stores the name of the institution that sponsored the KCWorks record. One intended use is for unpublished materials such white papers that were sponsored or commissioned by an institution. The field may also be used for the institution hosting a conference or workshop associated with the KCWorks record (as distinct from the organization that sponsored the event). + +Note that this field is not intended for the degree-granting institution associated with a thesis or dissertation. That institution's title should be stored in the `thesis:university` field. + +Example: +```json +{ + "kcr:sponsoring_institution": "University of Toronto" +} +``` + +### kcr:submitter_email + +Type: `string` (email address) + +This field stores the email address of the submitter of the KCWorks record. It must be a valid email address. + +Example: +```json +{ + "kcr:submitter_email": "john.doe@example.com" +} +``` + +### kcr:submitter_username + +Type: `string` + +This field stores the KC username of the submitter of the KCWorks record. This should be used even if the submitter is also a contributor to the KCWorks record and has included the same username in the `metadata.creators.person_or_org.identifiers` array. + +Example: +```json +{ + "kcr:submitter_username": "jdoe" +} +``` + +### kcr:institution_department + +Type: `string` + +This field stores the institutional department in which a thesis, dissertation, or other educational artifact was produced. It is intended to complement the `thesis:university` field, which stores the degree-granting institution. + +Example: +```json +{ + "kcr:institution_department": "Art History" +} +``` + +### kcr:book_series + +Type: `Object[string, string]` + +This field stores the title of a series that contains the KCWorks record, along with the optional volume number of the work within the series. + + +Example: +```json +{ + "kcr:book_series": { + "series_title": "The Complete Works of Jane Austen", + "series_volume": "Volume 1" + } +} +``` + +### kcr:user_defined_tags + +Type: `Array[string]` + +This field stores a list of user-defined tags for the KCWorks record. Unlike the `metadata.subjects` field, these tags are not constrained by any controlled vocabulary. Items should be free-form strings that describe the KCWorks record in a way that is not covered by the `metadata.subjects` field. + +> [!Note] +> The `kcr:user_defined_tags` field is intended to supplement the `metadata.subjects` field, not as the primary means of describing the KCWorks record's subject matter. Assigning proper `metadata.subjects` entries allows for much more effective search and discovery of the KCWorks record. + +Example: +```json +{ + "kcr:user_defined_tags": ["Ukranian refugees", "Migrants in Europe"] +} +``` + +### kcr:commons_search_recid (system field) + +This field is used to store the persistent identifier for the KCWorks record in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +### kcr:commons_search_updated (system field) + +Type: `string` (ISO 8601 datetime string) + +This field stores the date and time when the KCWorks record was last updated in the KC central search index. + +> [!Warning] +> This field is automatically generated by the `invenio-remote-api-provisioner` service when a KCWorks record is published. It *must not* be set by the user. + +## HC Legacy Custom Fields + +The `hclegacy` namespace is used for custom fields that are used to store data from the legacy CORE database. These fields should not be used for new data. + +### custom_fields.hclegacy:groups_for_deposit + +Type: `Array[Object[string, string]]` + +This field is used to store the groups to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks collections during migration. + +Example: +```json +{ + "hclegacy:groups_for_deposit": [ + { + "group_name": "Group Name", + "group_identifier": "Group Identifier" + } + ] +} +``` + +### custom_fields.hclegacy:collection + +Type: `string` + +This field is used to store the org collection to which a legacy CORE record belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration. + +Example: +```json +{ + "hclegacy:collection": "Collection Name" +} +``` + +### custom_fields.hclegacy:committee_deposit + +Type: `integer` + +This field is used to store the committee deposit number for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:committee_deposit": 123456 +} +``` + +### custom_fields.hclegacy:file_location + +Type: `string` + +This field is used to store the relative path the the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_location": "/path/to/file.pdf" +} +``` + +### custom_fields.hclegacy:file_pid + +Type: `string` + +This field is used to store the persistent identifier for the file for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:file_pid": "hc:123456" +} +``` + +### custom_fields.hclegacy:previously_published + +Type: `string` + +This field is used to store the previously published status for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:previously_published": "true" +} +``` + +### custom_fields.hclegacy:publication_type + +Type: `string` + +This field is used to store the publication type for a legacy CORE record. It was used during migration to help determine the KCWorks resource type of the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:publication_type": "Journal Article" +} +``` + +### custom_fields.hclegacy:record_change_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the last change to a legacy CORE record. It was not used during migration to KCWorks and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_change_date": "2024-01-01T00:00:00Z" +} +``` + +### custom_fields.hclegacy:record_creation_date + +Type: `string` (ISO 8601 datetime string) + +This field is used to store the date of the creation of a legacy CORE record. It was not used during migration because InvenioRDM does not allow overriding of the record creation date. It is only preserved for historical purposes and should not be used for new data. + +Example: +```json +{ + "hclegacy:record_creation_date": "2024-01-01T00:00:00Z" +} +``` + +### custom_fields.hclegacy:record_identifier + +Type: `string` + +This field is used to store the internal system identifier for a legacy CORE record. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:record_identifier": "1001634-1263" +} +``` + +### custom_fields.hclegacy:submitter_org_memberships + +Type: `array[string]` + +This field is used to store the organizations to which a legacy CORE record's submitter belonged before import into KCWorks. It was used to create corresponding KCWorks org collections during migration and assign the work to those org collections. + +Example: +```json +{ + "hclegacy:submitter_org_memberships": ["arlisna", "mla"] +} +``` + +### custom_fields.hclegacy:submitter_affiliation + +Type: `string` + +This field is used to store the organizational affiliation of a legacy CORE record's submitter at the time of import into KCWorks. It was not used during migration and is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_affiliation": "University of Toronto" +} +``` + +### custom_fields.hclegacy:submitter_id + +Type: `string` + +This field is used to store the internal KC system user id of a legacy CORE record's submitter. It was used during migration to assign ownership of the newly created record, and is preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:submitter_id": "123456" +} +``` + +### custom_fields.hclegacy:total_views + +Type: `integer` + +This field is used to store the total number of views for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_views": 123456 +} +``` + +### custom_fields.hclegacy:total_downloads + +Type: `integer` + +This field is used to store the total number of downloads for a legacy CORE record prior to import into KCWorks. It was used during migration to create KCWorks usage stats aggregations for the record. It is only preserved for historical purposes. It should not be used for new data. + +Example: +```json +{ + "hclegacy:total_downloads": 123456 +} +``` diff --git a/docs/source/reference.md b/docs/source/reference.md new file mode 100644 index 000000000..0b77fdd69 --- /dev/null +++ b/docs/source/reference.md @@ -0,0 +1,5 @@ +# Reference + +## InvenioRDM Documentation + +The Knowledge Commons Works is built as an instance of InvenioRDM. The InvenioRDM Documentation, including customization and development information, can be found at https://inveniordm.docs.cern.ch/. \ No newline at end of file diff --git a/invenio.cfg b/invenio.cfg index d405e8838..08ea1bec3 100644 --- a/invenio.cfg +++ b/invenio.cfg @@ -609,7 +609,19 @@ RDM_SEARCH_USER_COMMUNITIES = { "sort_default": "bestmatch", "sort_default_no_query": "newest", } -"""User communities search configuration (i.e list of user communities)""" +"""User communities search configuration (i.e list of user communities) +This affects the community search modal in the detail page. +""" + +COMMUNITIES_SEARCH = { + "facets": ["type", "visibility"], + "sort": ["bestmatch", "newest", "oldest"], + "sort_default": "bestmatch", + "sort_default_no_query": "newest", +} +"""Community search configuration (i.e list of communities) +This affects the community search modal in the upload form. +""" # Invenio-App-RDM # =============== diff --git a/site/kcworks/__init__.py b/site/kcworks/__init__.py index beec5bf94..fca2183cf 100644 --- a/site/kcworks/__init__.py +++ b/site/kcworks/__init__.py @@ -18,4 +18,4 @@ """KCWorks customizations to InvenioRDM.""" -__version__ = "0.3.3-beta6" +__version__ = "0.3.4-beta7" diff --git a/site/kcworks/metadata_fields/hclegacy_metadata_fields.py b/site/kcworks/metadata_fields/hclegacy_metadata_fields.py index de76dde81..bb01e7742 100644 --- a/site/kcworks/metadata_fields/hclegacy_metadata_fields.py +++ b/site/kcworks/metadata_fields/hclegacy_metadata_fields.py @@ -42,7 +42,7 @@ concatenates the site ID (id number for HC, MLA, etc.) and original item id number in the CORE database. hclegacy:society The HC societies to which the original uploader of - the CORE deposit belonged. It should include the society from whose site the deposit was made, although this may not be the case for bulk uploads. Possible values are: arlisna, hc, msu, ajs, hastac, sah, aseees, caa, up. + the CORE deposit belonged. It should include the society from whose site the deposit was made, although this may not be the case for bulk uploads. Possible values are: arlisna, hc, msu, ajs, hastac, sah, aseees, caa, up. (Deprecated and never used.) hclegacy:submitter_org_memberships The HC organizations to which the user who uploaded the deposit belonged. hclegacy:submitter_affiliation The institutional affiliation of the user @@ -106,7 +106,7 @@ field_cls=SanitizedUnicode, ), TextCF( - name="hclegacy:society", + name="hclegacy:society", # Deprecated and never used. field_cls=SanitizedUnicode, ), TextCF( diff --git a/site/pyproject.toml b/site/pyproject.toml index eb65cd41d..072a49e8a 100644 --- a/site/pyproject.toml +++ b/site/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "kcworks" -version = "0.3.3-beta6" +version = "0.3.4-beta7" [project.optional-dependencies] tests = ["pytest-invenio>=2.1.0,<3.0.0"]