From 50b9c0b45f8e65585acc91ff4ca8b844b4b8192b Mon Sep 17 00:00:00 2001 From: Julian Weng Date: Fri, 16 Feb 2024 17:48:01 -0500 Subject: [PATCH] Revert "Update ticketing (backend) branch (#612)" This reverts commit 03214afe42d3574029b38b47947611a622ce4fe6. --- .github/cdk/.gitignore | 3 + .github/cdk/cdkactions.yaml | 2 + .github/cdk/main.ts | 14 + .github/cdk/package.json | 25 + .github/cdk/tsconfig.json | 33 + .github/cdk/yarn.lock | 206 ++ .github/dependabot.yml | 12 + .github/workflows/build-and-deploy.yaml | 122 - .../cdkactions_build-and-deploy.yaml | 241 ++ .github/workflows/cdkactions_validate.yaml | 28 + .gitignore | 3 - .pre-commit-config.yaml | 5 +- README.md | 14 +- backend/Dockerfile | 2 +- backend/Pipfile | 9 +- backend/Pipfile.lock | 2087 +++++++------ backend/clubs/admin.py | 11 +- backend/clubs/management/commands/populate.py | 12 +- .../management/commands/update_club_counts.py | 36 - .../commands/wharton_council_application.py | 135 + ...0088_alter_applicationsubmission_status.py | 45 + ...0089_alter_applicationsubmission_status.py | 26 + .../migrations/0089_auto_20230103_1239.py | 60 - .../{0088_adminnote.py => 0090_adminnote.py} | 2 +- .../migrations/0090_auto_20230106_1443.py | 40 - .../migrations/0091_applicationextension.py | 47 - ...096_cart_ticket.py => 0091_cart_ticket.py} | 2 +- ...lication_application_end_time_exception.py | 18 - .../migrations/0092_merge_20240106_1117.py | 13 - .../migrations/0093_auto_20240106_1153.py | 23 - .../0094_applicationcycle_release_date.py | 18 - .../migrations/0095_rm_field_add_count.py | 34 - backend/clubs/mixins.py | 2 +- backend/clubs/models.py | 92 +- backend/clubs/serializers.py | 207 +- backend/clubs/urls.py | 17 +- backend/clubs/views.py | 947 +----- backend/pennclubs/settings/base.py | 2 +- backend/pennclubs/settings/production.py | 7 +- .../emails/application_extension.html | 22 - backend/templates/emails/renew.html | 2 +- .../templates/emails/renewal_reminder.html | 6 +- backend/tests/clubs/test_views.py | 70 +- frontend/components/Applications.tsx | 150 +- .../ClubEditPage/ApplicationsCard.tsx | 66 +- .../ClubEditPage/ApplicationsPage.tsx | 547 +--- frontend/components/ClubPage/Actions.tsx | 37 +- frontend/components/ClubPage/InfoBox.tsx | 6 +- .../ClubPage/RenewalRequestDialog.tsx | 4 +- frontend/components/CustomOption.tsx | 69 - frontend/components/DisplayButtons.tsx | 23 +- frontend/components/FormComponents.tsx | 90 +- frontend/components/Header/Links.tsx | 8 - frontend/components/ModelForm.tsx | 32 +- frontend/components/SearchBar.tsx | 2 +- .../Settings/WhartonApplicationCycles.tsx | 327 --- .../Settings/WhartonApplicationStatus.tsx | 15 - frontend/components/Submissions.tsx | 18 +- frontend/components/common/Table.tsx | 1 - .../application/[application]/index.tsx | 45 +- frontend/pages/club/[club]/apply.tsx | 8 +- frontend/pages/club/[club]/renew.tsx | 50 +- frontend/pages/fair.tsx | 106 +- frontend/pages/wharton/[[...slug]].tsx | 6 - frontend/types.ts | 13 - frontend/utils.tsx | 4 - frontend/utils/branding.tsx | 508 ++-- k8s/main.ts | 60 +- k8s/package.json | 57 +- k8s/yarn.lock | 2610 +++++++---------- 70 files changed, 3709 insertions(+), 5855 deletions(-) create mode 100644 .github/cdk/.gitignore create mode 100644 .github/cdk/cdkactions.yaml create mode 100644 .github/cdk/main.ts create mode 100644 .github/cdk/package.json create mode 100644 .github/cdk/tsconfig.json create mode 100644 .github/cdk/yarn.lock create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/build-and-deploy.yaml create mode 100644 .github/workflows/cdkactions_build-and-deploy.yaml create mode 100644 .github/workflows/cdkactions_validate.yaml delete mode 100644 backend/clubs/management/commands/update_club_counts.py create mode 100644 backend/clubs/management/commands/wharton_council_application.py create mode 100644 backend/clubs/migrations/0088_alter_applicationsubmission_status.py create mode 100644 backend/clubs/migrations/0089_alter_applicationsubmission_status.py delete mode 100644 backend/clubs/migrations/0089_auto_20230103_1239.py rename backend/clubs/migrations/{0088_adminnote.py => 0090_adminnote.py} (95%) delete mode 100644 backend/clubs/migrations/0090_auto_20230106_1443.py delete mode 100644 backend/clubs/migrations/0091_applicationextension.py rename backend/clubs/migrations/{0096_cart_ticket.py => 0091_cart_ticket.py} (98%) delete mode 100644 backend/clubs/migrations/0091_clubapplication_application_end_time_exception.py delete mode 100644 backend/clubs/migrations/0092_merge_20240106_1117.py delete mode 100644 backend/clubs/migrations/0093_auto_20240106_1153.py delete mode 100644 backend/clubs/migrations/0094_applicationcycle_release_date.py delete mode 100644 backend/clubs/migrations/0095_rm_field_add_count.py delete mode 100644 backend/templates/emails/application_extension.html delete mode 100644 frontend/components/CustomOption.tsx delete mode 100644 frontend/components/Settings/WhartonApplicationCycles.tsx diff --git a/.github/cdk/.gitignore b/.github/cdk/.gitignore new file mode 100644 index 000000000..794fce505 --- /dev/null +++ b/.github/cdk/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +main.js +main.d.ts diff --git a/.github/cdk/cdkactions.yaml b/.github/cdk/cdkactions.yaml new file mode 100644 index 000000000..626767947 --- /dev/null +++ b/.github/cdk/cdkactions.yaml @@ -0,0 +1,2 @@ +language: typescript +app: node main.js diff --git a/.github/cdk/main.ts b/.github/cdk/main.ts new file mode 100644 index 000000000..8a675c301 --- /dev/null +++ b/.github/cdk/main.ts @@ -0,0 +1,14 @@ +import { App } from "cdkactions"; +import { LabsApplicationStack } from '@pennlabs/kraken'; + + +const app = new App(); +new LabsApplicationStack(app, { + djangoProjectName: 'pennclubs', + dockerImageBaseName: 'penn-clubs', + integrationTests: true, + integrationProps: { + testCommand: 'docker-compose -f docker-compose.test.yaml exec -T frontend yarn integration', + }, +}); +app.synth(); diff --git a/.github/cdk/package.json b/.github/cdk/package.json new file mode 100644 index 000000000..7606d7034 --- /dev/null +++ b/.github/cdk/package.json @@ -0,0 +1,25 @@ +{ + "name": "cdk", + "version": "0.1.0", + "main": "main.js", + "types": "main.ts", + "license": "Apache-2.0", + "private": true, + "scripts": { + "synth": "cdkactions synth", + "compile": "tsc", + "watch": "tsc -w", + "build": "yarn compile && yarn synth", + "upgrade-cdk": "yarn upgrade cdkactions@latest cdkactions-cli@latest" + }, + "dependencies": { + "@pennlabs/kraken": "^0.8.6", + "cdkactions": "^0.2.1", + "constructs": "^3.3.136" + }, + "devDependencies": { + "@types/node": "^16.7.5", + "cdkactions-cli": "^0.2.3", + "typescript": "^4.4.2" + } +} diff --git a/.github/cdk/tsconfig.json b/.github/cdk/tsconfig.json new file mode 100644 index 000000000..936e05cef --- /dev/null +++ b/.github/cdk/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "alwaysStrict": true, + "charset": "utf8", + "declaration": true, + "experimentalDecorators": true, + "inlineSourceMap": true, + "inlineSources": true, + "lib": [ + "es2018" + ], + "module": "CommonJS", + "noEmitOnError": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "strict": true, + "strictNullChecks": true, + "strictPropertyInitialization": true, + "stripInternal": true, + "target": "ES2018" + }, + "include": [ + "**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/.github/cdk/yarn.lock b/.github/cdk/yarn.lock new file mode 100644 index 000000000..04c1005e0 --- /dev/null +++ b/.github/cdk/yarn.lock @@ -0,0 +1,206 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@pennlabs/kraken@^0.8.6": + version "0.8.6" + resolved "https://registry.yarnpkg.com/@pennlabs/kraken/-/kraken-0.8.6.tgz#79a9d10bed36b699c526556cd69b6d81341847d1" + integrity sha512-aBblQa/661DJ2GP3Dq1KEzCZ72ZV/Jw7z4HNZoWPxGWn+tSPwvaPkSNDpK7tT+nJmu427giGU8DLyciU79hKbA== + dependencies: + cdkactions "^0.2.3" + constructs "^3.2.80" + ts-dedent "^2.2.0" + +"@types/node@^16.7.5": + version "16.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.5.tgz#96142b243977b03d99c338fdb09241d286102711" + integrity sha512-E7SpxDXoHEpmZ9C1gSqwadhE6zPRtf3g0gJy9Y51DsImnR5TcDs3QEiV/3Q7zOM8LWaZp5Gph71NK6ElVMG1IQ== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +cdkactions-cli@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/cdkactions-cli/-/cdkactions-cli-0.2.3.tgz#2393682b37ab0b04c6964160b393e8d71b08118f" + integrity sha512-qYPbzuQ1M5gQGa8NRnaWwm3iXmdqMoiHR7YTh6oYROpfBGER7kwBBb6ydFlSwKK62hE0B++by43hbEBXlHvr8A== + dependencies: + cdkactions "^0.2.3" + constructs "^3.2.109" + fs-extra "^8.1.0" + sscaff "^1.2.0" + yaml "^1.10.0" + yargs "^16.2.0" + +cdkactions@^0.2.1, cdkactions@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/cdkactions/-/cdkactions-0.2.3.tgz#aa27bf720962376d54f8ef95cdfb0ab46458b966" + integrity sha512-/DYQ2qsT6fzgZB+cmQjtPqR4aAWCqAytWbFpJK+iJLQ4jQrl6l4uMf01TLiWY3mAILS0YGlwPcoBbGvq9Jnz5g== + dependencies: + js-yaml "^4.0.0" + ts-dedent "^2.0.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +constructs@^3.2.109, constructs@^3.2.80, constructs@^3.3.136: + version "3.3.136" + resolved "https://registry.yarnpkg.com/constructs/-/constructs-3.3.136.tgz#9a311737bb802f7931a1f38c5223d82fa3efd08d" + integrity sha512-8qGuZTTXxsV3uUtqbajcQhcuu28bcuYG5jODXlXWLpd4bSo+2dMg5vKLr0dsRm/Q3B7op7io1P0opMzaGdCO5A== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +js-yaml@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +sscaff@^1.2.0: + version "1.2.57" + resolved "https://registry.yarnpkg.com/sscaff/-/sscaff-1.2.57.tgz#ebd5b58ec6567f8a6684e5e2245fe2ece24b4c53" + integrity sha512-nQwKlWrf7fls8TJibFM8rMXVZYvcfHc2pSMKNO641p83U5/Aof1KyrnF39X5m2baX9/uZfPxe6SRHBWSpLMfyA== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +ts-dedent@^2.0.0, ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + +typescript@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.2.tgz#6d618640d430e3569a1dfb44f7d7e600ced3ee86" + integrity sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..f81e0b01f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/frontend" + schedule: + interval: "weekly" + open-pull-requests-limit: 0 + - package-ecosystem: "pip" + directory: "/backend" + schedule: + interval: "weekly" + open-pull-requests-limit: 0 diff --git a/.github/workflows/build-and-deploy.yaml b/.github/workflows/build-and-deploy.yaml deleted file mode 100644 index 358e3e6af..000000000 --- a/.github/workflows/build-and-deploy.yaml +++ /dev/null @@ -1,122 +0,0 @@ -# ======================================== -# Note: If you make changes to this CI/CD, please include someone from DevOps in the list of reviewers for the PR. -# ======================================== -name: Build and Deploy Clubs - -on: push - -jobs: - backend-check: - name: "Backend Check" - uses: pennlabs/shared-actions/.github/workflows/django.yaml@8785a7d7b9158d8d5705a0202f5695db2c0beb97 - with: - projectName: pennclubs - path: backend - flake: true - black: true - - frontend-check: - name: "Frontend Check" - uses: pennlabs/shared-actions/.github/workflows/react-check.yaml@v0.1 - with: - path: frontend - - build-backend: - name: Build backend - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: docker/setup-qemu-action@v1 - - uses: docker/setup-buildx-action@v1 - - name: Cache Docker layers - uses: actions/cache@v2 - with: - path: /tmp/.buildx-cache - key: buildx-build-backend - - name: Build/Publish - uses: docker/build-push-action@v2 - with: - context: backend - file: backend/Dockerfile - push: false - cache-from: type=local,src=/tmp/.buildx-cache,type=registry,ref=pennlabs/penn-clubs-backend:latest - cache-to: type=local,dest=/tmp/.buildx-cache - tags: pennlabs/penn-clubs-backend:latest,pennlabs/penn-clubs-backend:${{ github.sha }} - outputs: type=docker,dest=/tmp/image.tar - - uses: actions/upload-artifact@v2 - with: - name: build-backend - path: /tmp/image.tar - needs: backend-check - - build-frontend: - name: Build frontend - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: docker/setup-qemu-action@v1 - - uses: docker/setup-buildx-action@v1 - - name: Cache Docker layers - uses: actions/cache@v2 - with: - path: /tmp/.buildx-cache - key: buildx-build-frontend - - name: Build/Publish - uses: docker/build-push-action@v2 - with: - context: frontend - file: frontend/Dockerfile - push: false - cache-from: type=local,src=/tmp/.buildx-cache,type=registry,ref=pennlabs/penn-clubs-frontend:latest - cache-to: type=local,dest=/tmp/.buildx-cache - tags: pennlabs/penn-clubs-frontend:latest,pennlabs/penn-clubs-frontend:${{ github.sha }} - outputs: type=docker,dest=/tmp/image.tar - - uses: actions/upload-artifact@v2 - with: - name: build-frontend - path: /tmp/image.tar - needs: frontend-check - - publish: - name: Publish Images - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/master' - steps: - - uses: actions/checkout@v2 - - uses: actions/download-artifact@v2 - - uses: geekyeggo/delete-artifact@v1 - with: - name: |- - build-backend - build-frontend - - name: Load docker images - run: |- - docker load --input build-backend/image.tar - docker load --input build-frontend/image.tar - - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Push docker images - run: |- - docker push -a pennlabs/penn-clubs-backend - docker push -a pennlabs/penn-clubs-frontend - needs: - - build-backend - - build-frontend - - deploy: - name: "Deploy" - uses: pennlabs/shared-actions/.github/workflows/deployment.yaml@v0.1 - - with: - githubRef: ${{ github.ref }} - gitSha: ${{ github.sha }} - - secrets: - AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} - GH_AWS_ACCESS_KEY_ID: ${{ secrets.GH_AWS_ACCESS_KEY_ID }} - GH_AWS_SECRET_ACCESS_KEY: ${{ secrets.GH_AWS_SECRET_ACCESS_KEY }} - - needs: - - publish diff --git a/.github/workflows/cdkactions_build-and-deploy.yaml b/.github/workflows/cdkactions_build-and-deploy.yaml new file mode 100644 index 000000000..46ae7ee89 --- /dev/null +++ b/.github/workflows/cdkactions_build-and-deploy.yaml @@ -0,0 +1,241 @@ +# Generated by cdkactions. Do not modify +# Generated as part of the 'application' stack. +name: Build and Deploy +on: push +jobs: + django-check: + name: Django Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Cache + uses: actions/cache@v2 + with: + path: ~/.local/share/virtualenvs + key: v0-${{ hashFiles('backend/Pipfile.lock') }} + - name: Install Dependencies + run: |- + cd backend + pip install pipenv + pipenv install --deploy --dev + - name: Lint (flake8) + run: |- + cd backend + pipenv run flake8 . + - name: Lint (black) + run: |- + cd backend + pipenv run black --check . + - name: Test (run in parallel) + run: |- + cd backend + pipenv run coverage run --concurrency=multiprocessing manage.py test --settings=pennclubs.settings.ci --parallel + pipenv run coverage combine + - name: Upload Code Coverage + run: |- + ROOT=$(pwd) + cd backend + pipenv run codecov --root $ROOT --flags backend + container: + image: python:3.8-buster + env: + DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres + services: + postgres: + image: postgres:12 + env: + POSTGRES_USER: postgres + POSTGRES_DB: postgres + POSTGRES_PASSWORD: postgres + options: "--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5" + build-backend: + name: Build backend + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: docker/setup-qemu-action@v1 + - uses: docker/setup-buildx-action@v1 + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: buildx-build-backend + - name: Build/Publish + uses: docker/build-push-action@v2 + with: + context: backend + file: backend/Dockerfile + push: false + cache-from: type=local,src=/tmp/.buildx-cache,type=registry,ref=pennlabs/penn-clubs-backend:latest + cache-to: type=local,dest=/tmp/.buildx-cache + tags: pennlabs/penn-clubs-backend:latest,pennlabs/penn-clubs-backend:${{ github.sha }} + outputs: type=docker,dest=/tmp/image.tar + - uses: actions/upload-artifact@v2 + with: + name: build-backend + path: /tmp/image.tar + needs: django-check + react-check: + name: React Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Cache + uses: actions/cache@v2 + with: + path: "**/node_modules" + key: v0-${{ hashFiles('frontend/yarn.lock') }} + - name: Install Dependencies + run: |- + cd frontend + yarn install --frozen-lockfile + - name: Lint + run: |- + cd frontend + yarn lint + - name: Test + run: |- + cd frontend + yarn test + - name: Upload Code Coverage + run: |- + ROOT=$(pwd) + cd frontend + yarn run codecov -p $ROOT -F frontend + container: + image: node:14 + build-frontend: + name: Build frontend + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: docker/setup-qemu-action@v1 + - uses: docker/setup-buildx-action@v1 + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: buildx-build-frontend + - name: Build/Publish + uses: docker/build-push-action@v2 + with: + context: frontend + file: frontend/Dockerfile + push: false + cache-from: type=local,src=/tmp/.buildx-cache,type=registry,ref=pennlabs/penn-clubs-frontend:latest + cache-to: type=local,dest=/tmp/.buildx-cache + tags: pennlabs/penn-clubs-frontend:latest,pennlabs/penn-clubs-frontend:${{ github.sha }} + outputs: type=docker,dest=/tmp/image.tar + - uses: actions/upload-artifact@v2 + with: + name: build-frontend + path: /tmp/image.tar + needs: react-check + integration-tests: + name: Integration Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + - name: Load docker images + run: |- + docker load --input build-backend/image.tar + docker load --input build-frontend/image.tar + - name: Run docker compose + run: |- + mkdir -p /tmp/test-results + docker-compose -f docker-compose.test.yaml up -d + - name: Wait for backend + run: |- + for try in {1..20}; do + docker-compose -f docker-compose.test.yaml exec -T backend python manage.py migrate --check && break + sleep 5 + done + - name: Populate backend + run: docker-compose -f docker-compose.test.yaml exec -T backend python manage.py populate + - name: Run integration tests + run: docker-compose -f docker-compose.test.yaml exec -T frontend yarn integration + - name: Delete artifacts when no longer needed + if: failure() || github.ref != 'refs/heads/master' + uses: geekyeggo/delete-artifact@v1 + with: + name: |- + build-backend + build-frontend + - name: Print logs on failure + if: failure() + run: docker-compose -f docker-compose.test.yaml logs + - name: Upload artifacts on failure + if: failure() + uses: actions/upload-artifact@v2 + with: + name: cypress-output + path: /tmp/test-results + env: + GIT_SHA: ${{ github.sha }} + needs: + - build-backend + - build-frontend + post-integration-publish: + name: Publish Images + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v2 + - uses: actions/download-artifact@v2 + - uses: geekyeggo/delete-artifact@v1 + with: + name: |- + build-backend + build-frontend + - name: Load docker images + run: |- + docker load --input build-backend/image.tar + docker load --input build-frontend/image.tar + - uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Push docker images + run: |- + docker push -a pennlabs/penn-clubs-backend + docker push -a pennlabs/penn-clubs-frontend + needs: integration-tests + deploy: + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v2 + - id: synth + name: Synth cdk8s manifests + run: |- + cd k8s + yarn install --frozen-lockfile + + # get repo name (by removing owner/organization) + export RELEASE_NAME=${REPOSITORY#*/} + + # Export RELEASE_NAME as an output + echo "::set-output name=RELEASE_NAME::$RELEASE_NAME" + + yarn build + env: + GIT_SHA: ${{ github.sha }} + REPOSITORY: ${{ github.repository }} + AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} + - name: Deploy + run: |- + aws eks --region us-east-1 update-kubeconfig --name production --role-arn arn:aws:iam::${AWS_ACCOUNT_ID}:role/kubectl + + # get repo name from synth step + RELEASE_NAME=${{ steps.synth.outputs.RELEASE_NAME }} + + # Deploy + kubectl apply -f k8s/dist/ -l app.kubernetes.io/component=certificate + kubectl apply -f k8s/dist/ --prune -l app.kubernetes.io/part-of=$RELEASE_NAME + env: + AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} + AWS_ACCESS_KEY_ID: ${{ secrets.GH_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.GH_AWS_SECRET_ACCESS_KEY }} + needs: + - post-integration-publish diff --git a/.github/workflows/cdkactions_validate.yaml b/.github/workflows/cdkactions_validate.yaml new file mode 100644 index 000000000..73834d779 --- /dev/null +++ b/.github/workflows/cdkactions_validate.yaml @@ -0,0 +1,28 @@ +# Generated by cdkactions. Do not modify +# Generated as part of the 'validate' stack. +name: Validate cdkactions manifests +on: push +jobs: + validate: + name: Validate cdkactions manifests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + token: ${{ github.token }} + - name: Validate manifests + run: |- + cd .github/cdk + yarn install + yarn build + git --no-pager diff ../workflows + git diff-index --quiet HEAD -- ../workflows + - name: Push updated manifests + if: "false" + run: |- + cd .github/workflows + git config user.name github-actions + git config user.email github-actions[bot]@users.noreply.github.com + git add . + git commit -m "Update cdkactions manifests" || exit 0 + git push diff --git a/.gitignore b/.gitignore index 35a1877f2..3cd5296e7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ # Python files __pycache__/ *.pyc -.python-version # Distribution /frontend/public/storybook/ @@ -28,8 +27,6 @@ db.sqlite3 # React node_modules/ -.yarn -.yarnrc.yml .next/ # Development Enviroment diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 64a465e47..9f5abe424 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,12 +4,11 @@ repos: hooks: - id: black name: black - entry: bash -c "export PIPENV_IGNORE_VIRTUALENVS=1 && cd backend && pipenv run black ." + entry: cd backend && pipenv run black language: python types: [python] require_serial: true files: ^backend/ - pass_filenames: false - id: isort name: isort entry: isort @@ -27,7 +26,7 @@ repos: args: [--config, backend/setup.cfg] - id: frontend name: Yarn Linter - entry: bash -c "cd frontend && yarn lint" + entry: yarn --cwd frontend lint language: system files: ^frontend/ require_serial: false diff --git a/README.md b/README.md index ff2f12a9b..e9552e195 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ Official React-based website for Penn Labs' club directory and events listings. The REST API written in Django for Penn Clubs infrastructure. ## Installation - You will need to start both the backend and the frontend to do Penn Clubs development. Questions? Check out our [extended guide](https://github.com/pennlabs/penn-clubs/wiki/Development-Guide#windows-development) for FAQs for both Mac and Windows. @@ -17,7 +16,6 @@ Questions? Check out our [extended guide](https://github.com/pennlabs/penn-clubs Running the backend requires [Python 3](https://www.python.org/downloads/). In production, you will need to set the following environment variables: - - `NEXT_PUBLIC_SITE_NAME` (optional, defaults to `clubs`) - `SECRET_KEY` - `SENTRY_URL` @@ -29,7 +27,6 @@ In production, you will need to set the following environment variables: - `LABS_CLIENT_SECRET` (from Platform) To run the server, `cd` to the folder where you cloned `penn-clubs`. Then run: - - `cd backend` Setting up `psycopg2` (this is necessary if you want to be able to modify @@ -45,14 +42,14 @@ dependencies, you can revisit later if not) - Windows - `$ apt-get install gcc python3-dev libpq-dev` -Now, you can run +Now, you can run - `$ pipenv install` to install Python dependencies. This may take a few minutes. Optionally include the `--dev` argument if you are installing locally for development. If you skipped installing `psycopg2` earlier, you might see an error with locking -- this is expected! - `$ pipenv shell` -- `$ pre-commit install` +- `$ pre-commit install` - `$ ./manage.py migrate` OR `$ python3 manage.py migrate` - `$ ./manage.py populate` OR `$ python3 manage.py populate` (in development, to populate the database with dummy data) @@ -60,14 +57,9 @@ Now, you can run ### Frontend -Running the frontend requires [Node.js](https://nodejs.org/en/) and -[Yarn](https://yarnpkg.com/getting-started/install). - -**Please ensure you are using Node 14**. Our codebase does not support other -versions of Node (v14.21.3 is stable). +Running the frontend requires [Node.js](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com/getting-started/install). You will need to set the following environment variables on the frontend: - - `NEXT_PUBLIC_GOOGLE_API_KEY` - `NEXT_PUBLIC_SITE_NAME` (Optional) - Specify `clubs` to show Penn Clubs and `fyh` to show Hub@Penn. diff --git a/backend/Dockerfile b/backend/Dockerfile index b58dc4d80..9c9f86b52 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM pennlabs/django-base:9c4f31bf1af44219d0f9019271a0033a222291c2-3.8.5 +FROM pennlabs/django-base:a142aa6975ee293bbc8a09ef0b81998ce7063dd3 LABEL maintainer="Penn Labs" diff --git a/backend/Pipfile b/backend/Pipfile index 15e55c7a9..01c5b61a8 100644 --- a/backend/Pipfile +++ b/backend/Pipfile @@ -4,9 +4,10 @@ url = "https://pypi.org/simple" verify_ssl = true [dev-packages] +codecov = "*" black = "==19.10b0" unittest-xml-reporting = ">=3.0.2" -flake8 = "==5.0.3" +flake8 = "*" flake8-isort = "*" isort = "*" flake8-quotes = "*" @@ -31,6 +32,7 @@ pillow = "*" django-phonenumber-field = "*" phonenumbers = "*" qrcode = "*" +drf-renderer-xlsx = "==0.3.9" python-dateutil = "*" psycopg2 = "*" django-simple-history = "*" @@ -52,11 +54,6 @@ tblib = "*" pre-commit = "*" django-clone = "*" click = "==8.0.4" -jinja2 = "*" -pandas = "*" -drf-excel = "*" -numpy = "*" -coverage = "*" [requires] python_version = "3" diff --git a/backend/Pipfile.lock b/backend/Pipfile.lock index 3831da635..6c195adb4 100644 --- a/backend/Pipfile.lock +++ b/backend/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d2ae42ea3dc4d5de0bc9f2be6e0603264bfe0f248a0209f224b40ef941770a35" + "sha256": "1e5ed3497a97d54da1163f9def2f5aee2feaf2aa537a361d42376f30cb8cac4f" }, "pipfile-spec": 6, "requires": { @@ -16,13 +16,20 @@ ] }, "default": { + "aioredis": { + "hashes": [ + "sha256:15f8af30b044c771aee6787e5ec24694c048184c7b9e54c3b60c750a4b93273a", + "sha256:b61808d7e97b7cd5a92ed574937a079c9387fdadd22bfbfa7ad2fd319ecc26e3" + ], + "version": "==1.3.1" + }, "anyio": { "hashes": [ - "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421", - "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3" + "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b", + "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be" ], "markers": "python_full_version >= '3.6.2'", - "version": "==3.6.2" + "version": "==3.6.1" }, "arrow": { "hashes": [ @@ -34,49 +41,49 @@ }, "asgiref": { "hashes": [ - "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac", - "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506" + "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4", + "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424" ], "markers": "python_version >= '3.7'", - "version": "==3.6.0" + "version": "==3.5.2" }, "async-timeout": { "hashes": [ "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" ], - "markers": "python_full_version <= '3.11.2'", + "markers": "python_version >= '3.6'", "version": "==4.0.2" }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "autobahn": { "hashes": [ - "sha256:c5ef8ca7422015a1af774a883b8aef73d4954c9fcd182c9b5244e08e973f7c3a" + "sha256:8b462ea2e6aad6b4dc0ed45fb800b6cbfeb0325e7fe6983907f122f2be4a1fe9" ], "markers": "python_version >= '3.7'", - "version": "==23.1.2" + "version": "==22.7.1" }, "automat": { "hashes": [ - "sha256:c3164f8742b9dc440f3682482d32aaff7bb53f71740dd018533f9de286b64180", - "sha256:e56beb84edad19dcc11d30e8d9b895f75deeb5ef5e96b84a467066b3b84bb04e" + "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33", + "sha256:b6feb6455337df834f6c9962d6ccf771515b7d939bca142b29c20c2376bc6111" ], - "version": "==22.10.0" + "version": "==20.2.0" }, "beautifulsoup4": { "hashes": [ - "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da", - "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a" + "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30", + "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693" ], - "markers": "python_version >= '3.6'", - "version": "==4.12.2" + "markers": "python_full_version >= '3.6.0'", + "version": "==4.11.1" }, "bleach": { "hashes": [ @@ -88,19 +95,19 @@ }, "boto3": { "hashes": [ - "sha256:1ff703152553f4d5fc9774071d114dbf06ec661eb1b29b6051f6b1f9d0c24873", - "sha256:d0ed43228952b55c9f44d1c733f74656418c39c55dbe36bc37feeef6aa583ded" + "sha256:6194763348545bb1669ce8d03ba104be1ba822daa184613aa10b9303a6a79017", + "sha256:be151711bbb4db53e85dd5bbe506002ce6f2f21fc4e45fcf6d2cf356d32cc4c6" ], "index": "pypi", - "version": "==1.26.118" + "version": "==1.24.84" }, "botocore": { "hashes": [ - "sha256:44cb088a73b02dd716c5c5715143a64d5f10388957285246e11f3cc893eebf9d", - "sha256:b51fc5d50cbc43edaf58b3ec4fa933b82755801c453bf8908c8d3e70ae1142c1" + "sha256:11f05d2acdf9a5f722856704b7b951b180647fb4340e1b5048b27273dc323909", + "sha256:da15026329706caf83323d84996f5ff5c527837347633fca9b3b1be0efa60841" ], "markers": "python_version >= '3.7'", - "version": "==1.29.118" + "version": "==1.27.84" }, "bs4": { "hashes": [ @@ -111,11 +118,11 @@ }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", + "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2022.9.24" }, "cffi": { "hashes": [ @@ -204,92 +211,19 @@ }, "channels-redis": { "hashes": [ - "sha256:3696f5b9fe367ea495d402ba83d7c3c99e8ca0e1354ff8d913535976ed0abf73", - "sha256:6bd4f75f4ab4a7db17cee495593ace886d7e914c66f8214a1f247ff6659c073a" + "sha256:78e4a2f2b2a744fe5a87848ec36b5ee49f522c6808cefe6c583663d0d531faa8", + "sha256:ba7e2ad170f273c372812dd32aaac102d68d4e508172abb1cfda3160b7333890" ], "index": "pypi", - "version": "==4.1.0" + "version": "==3.4.1" }, "charset-normalizer": { "hashes": [ - "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6", - "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1", - "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e", - "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373", - "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62", - "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230", - "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be", - "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c", - "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0", - "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448", - "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f", - "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649", - "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d", - "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0", - "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706", - "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a", - "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59", - "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23", - "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5", - "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb", - "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e", - "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e", - "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c", - "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28", - "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d", - "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41", - "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974", - "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce", - "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f", - "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1", - "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d", - "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8", - "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017", - "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31", - "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7", - "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8", - "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e", - "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14", - "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd", - "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d", - "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795", - "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b", - "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b", - "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b", - "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203", - "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f", - "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19", - "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1", - "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a", - "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac", - "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9", - "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0", - "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137", - "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f", - "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6", - "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5", - "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909", - "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f", - "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0", - "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324", - "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755", - "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb", - "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854", - "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c", - "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60", - "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84", - "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0", - "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b", - "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1", - "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531", - "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1", - "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11", - "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326", - "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df", - "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab" + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" ], - "markers": "python_version >= '3.7'", - "version": "==3.1.0" + "markers": "python_full_version >= '3.6.0'", + "version": "==2.1.1" }, "click": { "hashes": [ @@ -314,88 +248,37 @@ ], "version": "==15.1.0" }, - "coverage": { - "hashes": [ - "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34", - "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e", - "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7", - "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b", - "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3", - "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985", - "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95", - "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2", - "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a", - "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74", - "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd", - "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af", - "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54", - "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865", - "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214", - "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54", - "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe", - "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0", - "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321", - "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446", - "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e", - "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527", - "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12", - "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f", - "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f", - "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84", - "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479", - "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e", - "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873", - "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70", - "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0", - "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977", - "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51", - "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28", - "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1", - "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254", - "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1", - "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd", - "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689", - "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d", - "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543", - "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9", - "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637", - "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071", - "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482", - "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1", - "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b", - "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5", - "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a", - "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393", - "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a", - "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba" - ], - "index": "pypi", - "version": "==7.3.0" - }, "cryptography": { "hashes": [ - "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440", - "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288", - "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b", - "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958", - "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b", - "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d", - "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a", - "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404", - "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b", - "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e", - "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2", - "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c", - "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b", - "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9", - "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b", - "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636", - "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99", - "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e", - "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9" + "sha256:0297ffc478bdd237f5ca3a7dc96fc0d315670bfa099c04dc3a4a2172008a405a", + "sha256:10d1f29d6292fc95acb597bacefd5b9e812099d75a6469004fd38ba5471a977f", + "sha256:16fa61e7481f4b77ef53991075de29fc5bacb582a1244046d2e8b4bb72ef66d0", + "sha256:194044c6b89a2f9f169df475cc167f6157eb9151cc69af8a2a163481d45cc407", + "sha256:1db3d807a14931fa317f96435695d9ec386be7b84b618cc61cfa5d08b0ae33d7", + "sha256:3261725c0ef84e7592597606f6583385fed2a5ec3909f43bc475ade9729a41d6", + "sha256:3b72c360427889b40f36dc214630e688c2fe03e16c162ef0aa41da7ab1455153", + "sha256:3e3a2599e640927089f932295a9a247fc40a5bdf69b0484532f530471a382750", + "sha256:3fc26e22840b77326a764ceb5f02ca2d342305fba08f002a8c1f139540cdfaad", + "sha256:5067ee7f2bce36b11d0e334abcd1ccf8c541fc0bbdaf57cdd511fdee53e879b6", + "sha256:52e7bee800ec869b4031093875279f1ff2ed12c1e2f74923e8f49c916afd1d3b", + "sha256:64760ba5331e3f1794d0bcaabc0d0c39e8c60bf67d09c93dc0e54189dfd7cfe5", + "sha256:765fa194a0f3372d83005ab83ab35d7c5526c4e22951e46059b8ac678b44fa5a", + "sha256:79473cf8a5cbc471979bd9378c9f425384980fcf2ab6534b18ed7d0d9843987d", + "sha256:896dd3a66959d3a5ddcfc140a53391f69ff1e8f25d93f0e2e7830c6de90ceb9d", + "sha256:89ed49784ba88c221756ff4d4755dbc03b3c8d2c5103f6d6b4f83a0fb1e85294", + "sha256:ac7e48f7e7261207d750fa7e55eac2d45f720027d5703cd9007e9b37bbb59ac0", + "sha256:ad7353f6ddf285aeadfaf79e5a6829110106ff8189391704c1d8801aa0bae45a", + "sha256:b0163a849b6f315bf52815e238bc2b2346604413fa7c1601eea84bcddb5fb9ac", + "sha256:b6c9b706316d7b5a137c35e14f4103e2115b088c412140fdbd5f87c73284df61", + "sha256:c2e5856248a416767322c8668ef1845ad46ee62629266f84a8f007a317141013", + "sha256:ca9f6784ea96b55ff41708b92c3f6aeaebde4c560308e5fbbd3173fbc466e94e", + "sha256:d1a5bd52d684e49a36582193e0b89ff267704cd4025abefb9e26803adeb3e5fb", + "sha256:d3971e2749a723e9084dd507584e2a2761f78ad2c638aa31e80bc7a15c9db4f9", + "sha256:d4ef6cc305394ed669d4d9eebf10d3a101059bdcf2669c366ec1d14e4fb227bd", + "sha256:d9e69ae01f99abe6ad646947bba8941e896cb3aa805be2597a0400e0764b5818" ], "markers": "python_version >= '3.6'", - "version": "==40.0.2" + "version": "==38.0.1" }, "daphne": { "hashes": [ @@ -429,51 +312,51 @@ }, "dj-database-url": { "hashes": [ - "sha256:80a115bd7675c9fe14a900b2f8b5c8b1822b5a279b333bf9b2804de681656c7c", - "sha256:87be5f7c4c83d9b3d8ce94b834f96cea14b3986f3629aac097afdd9318d7b098" + "sha256:ccf3e8718f75ddd147a1e212fca88eecdaa721759ee48e38b485481c77bca3dc", + "sha256:cd354a3b7a9136d78d64c17b2aec369e2ae5616fbca6bfbe435ef15bb372ce39" ], "index": "pypi", - "version": "==1.3.0" + "version": "==1.0.0" }, "django": { "hashes": [ - "sha256:08208dfe892eb64fff073ca743b3b952311104f939e7f6dae954fe72dcc533ba", - "sha256:4d492d9024c7b3dfababf49f94511ab6a58e2c9c3c7207786f1ba4eb77750706" + "sha256:115baf5049d5cf4163e43492cdc7139c306ed6d451e7d3571fe9612903903713", + "sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b" ], "index": "pypi", - "version": "==3.2.18" + "version": "==3.2.15" }, "django-clone": { "hashes": [ - "sha256:4be26e42bccd14e0ce24e3fa8d06744f904194e6ed7669d01034f7e81865e2e4", - "sha256:d44521a1680a0adbfff77429d1a4f9906ead3b31e5ee206d849883e32a6fd61f" + "sha256:0d12b4d976ed9be5ac19108f8551f017f79042b6676307c92fb8cfc530df861a", + "sha256:f3bc1e06799a82770da6c8fd6abcdbf1fd41390e7ea14a0cc5a8f12c0765d36e" ], "index": "pypi", - "version": "==5.3.1" + "version": "==3.0.6" }, "django-cors-headers": { "hashes": [ - "sha256:5fbd58a6fb4119d975754b2bc090f35ec160a8373f276612c675b00e8a138739", - "sha256:684180013cc7277bdd8702b80a3c5a4b3fcae4abb2bf134dceb9f5dfe300228e" + "sha256:37e42883b5f1f2295df6b4bba96eb2417a14a03270cb24b2a07f021cd4487cf4", + "sha256:f9dc6b4e3f611c3199700b3e5f3398c28757dcd559c2f82932687f3d0443cfdf" ], "index": "pypi", - "version": "==3.14.0" + "version": "==3.13.0" }, "django-labs-accounts": { "hashes": [ - "sha256:59e90ad8cb5201da5bbdbf68fab99eb25ca9a5d1ab577e0772ecbffcb470e15f", - "sha256:d360e13776a56998871289a66e855637ca740873f540da6923195e79d098491d" + "sha256:32cf0f705c53fb4624eea7326c77e37706f496462bb4125fb488547a3af187b2", + "sha256:fa537531f019c7668251455b1e586bcd6aa1dfb748198a6c1a5ef96972b6eae4" ], "index": "pypi", - "version": "==0.9.2" + "version": "==0.8.0" }, "django-phonenumber-field": { "hashes": [ - "sha256:9edad2b2602af25f2aefc73c4cf53eaf7abf9e17d73c1c4372bd3052bebb26f9", - "sha256:de3e47b986b4959949762c16fd8fe26b3e462ef3e5531ed00950bd20c698576a" + "sha256:dab78094e83f4b1276effca9903e6728e940d055b00cc8589ad5b8a22cb6a03b", + "sha256:f1aaee276b18a8f0bf503d52eda183965ca164a6379c1e70f73718bcc8a91345" ], "index": "pypi", - "version": "==7.0.2" + "version": "==7.0.0" }, "django-redis": { "hashes": [ @@ -493,19 +376,18 @@ }, "django-simple-history": { "hashes": [ - "sha256:2313d2d346f15a1e7a92adb3b6696b226f1cd0c1d920869ec40c4c4076614c41", - "sha256:dc1f98e558a0a1e0b6371c3b8efb85f86e02a6db56e83d0ec198343b7408d00a" + "sha256:eab6dbddb7da756cc5579f7d6f28a32b2e8bb1697a5c37794d96309793ffec38" ], "index": "pypi", - "version": "==3.3.0" + "version": "==3.1.1" }, "django-storages": { "hashes": [ - "sha256:31dc5a992520be571908c4c40d55d292660ece3a55b8141462b4e719aa38eab3", - "sha256:cbadd15c909ceb7247d4ffc503f12a9bec36999df8d0bef7c31e57177d512688" + "sha256:3540b45618b04be2c867c0982e8d2bd8e34f84dae922267fcebe4691fb93daf0", + "sha256:b3d98ecc09f1b1627c2b2cf430964322ce4e08617dbf9b4236c16a32875a1e0b" ], "index": "pypi", - "version": "==1.13.2" + "version": "==1.13.1" }, "djangorestframework": { "hashes": [ @@ -515,14 +397,6 @@ "index": "pypi", "version": "==3.14.0" }, - "drf-excel": { - "hashes": [ - "sha256:01905346446f699a03ffefe97edeff7e0d83e707028df2d593bf18381a148872", - "sha256:3ef1ce054c52f9850c46f4d4d3344e7fc8e6a95d9d0e0fb666d0bb6c37c38666" - ], - "index": "pypi", - "version": "==2.3.0" - }, "drf-nested-routers": { "hashes": [ "sha256:01aa556b8c08608bb74fb34f6ca065a5183f2cda4dc0478192cc17a2581d71b0", @@ -531,6 +405,14 @@ "index": "pypi", "version": "==0.93.4" }, + "drf-renderer-xlsx": { + "hashes": [ + "sha256:2aca180c71b088b1f8fa9adecb675f369f88cb89d46fd36f267ae166dc58332f", + "sha256:da19cbd973c59f8b5a0aa3d46f5888d3eddccf1c7a424a42d6748c81d4e1148f" + ], + "index": "pypi", + "version": "==0.3.9" + }, "et-xmlfile": { "hashes": [ "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c", @@ -539,21 +421,20 @@ "markers": "python_version >= '3.6'", "version": "==1.1.0" }, - "exceptiongroup": { + "filelock": { "hashes": [ - "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9", - "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3" + "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc", + "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4" ], - "markers": "python_version < '3.11'", - "version": "==1.1.3" + "markers": "python_version >= '3.7'", + "version": "==3.8.0" }, - "filelock": { + "future": { "hashes": [ - "sha256:ad98852315c2ab702aeb628412cbf7e95b7ce8c3bf9565670b4eaecf1db370a9", - "sha256:fc03ae43288c013d2ea83c8597001b1129db351aad9c57fe2409327916b8e718" + "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d" ], - "markers": "python_version >= '3.7'", - "version": "==3.12.0" + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.18.2" }, "gunicorn": { "hashes": [ @@ -571,6 +452,53 @@ "markers": "python_version >= '3.7'", "version": "==0.14.0" }, + "hiredis": { + "hashes": [ + "sha256:04026461eae67fdefa1949b7332e488224eac9e8f2b5c58c98b54d29af22093e", + "sha256:04927a4c651a0e9ec11c68e4427d917e44ff101f761cd3b5bc76f86aaa431d27", + "sha256:07bbf9bdcb82239f319b1f09e8ef4bdfaec50ed7d7ea51a56438f39193271163", + "sha256:09004096e953d7ebd508cded79f6b21e05dff5d7361771f59269425108e703bc", + "sha256:0adea425b764a08270820531ec2218d0508f8ae15a448568109ffcae050fee26", + "sha256:0b39ec237459922c6544d071cdcf92cbb5bc6685a30e7c6d985d8a3e3a75326e", + "sha256:0d5109337e1db373a892fdcf78eb145ffb6bbd66bb51989ec36117b9f7f9b579", + "sha256:0f41827028901814c709e744060843c77e78a3aca1e0d6875d2562372fcb405a", + "sha256:11d119507bb54e81f375e638225a2c057dda748f2b1deef05c2b1a5d42686048", + "sha256:1233e303645f468e399ec906b6b48ab7cd8391aae2d08daadbb5cad6ace4bd87", + "sha256:139705ce59d94eef2ceae9fd2ad58710b02aee91e7fa0ccb485665ca0ecbec63", + "sha256:1f03d4dadd595f7a69a75709bc81902673fa31964c75f93af74feac2f134cc54", + "sha256:240ce6dc19835971f38caf94b5738092cb1e641f8150a9ef9251b7825506cb05", + "sha256:294a6697dfa41a8cba4c365dd3715abc54d29a86a40ec6405d677ca853307cfb", + "sha256:3d55e36715ff06cdc0ab62f9591607c4324297b6b6ce5b58cb9928b3defe30ea", + "sha256:3dddf681284fe16d047d3ad37415b2e9ccdc6c8986c8062dbe51ab9a358b50a5", + "sha256:3f5f7e3a4ab824e3de1e1700f05ad76ee465f5f11f5db61c4b297ec29e692b2e", + "sha256:508999bec4422e646b05c95c598b64bdbef1edf0d2b715450a078ba21b385bcc", + "sha256:5d2a48c80cf5a338d58aae3c16872f4d452345e18350143b3bf7216d33ba7b99", + "sha256:5dc7a94bb11096bc4bffd41a3c4f2b958257085c01522aa81140c68b8bf1630a", + "sha256:65d653df249a2f95673976e4e9dd7ce10de61cfc6e64fa7eeaa6891a9559c581", + "sha256:7492af15f71f75ee93d2a618ca53fea8be85e7b625e323315169977fae752426", + "sha256:7f0055f1809b911ab347a25d786deff5e10e9cf083c3c3fd2dd04e8612e8d9db", + "sha256:807b3096205c7cec861c8803a6738e33ed86c9aae76cac0e19454245a6bbbc0a", + "sha256:81d6d8e39695f2c37954d1011c0480ef7cf444d4e3ae24bc5e89ee5de360139a", + "sha256:87c7c10d186f1743a8fd6a971ab6525d60abd5d5d200f31e073cd5e94d7e7a9d", + "sha256:8b42c0dc927b8d7c0eb59f97e6e34408e53bc489f9f90e66e568f329bff3e443", + "sha256:a00514362df15af041cc06e97aebabf2895e0a7c42c83c21894be12b84402d79", + "sha256:a39efc3ade8c1fb27c097fd112baf09d7fd70b8cb10ef1de4da6efbe066d381d", + "sha256:a4ee8000454ad4486fb9f28b0cab7fa1cd796fc36d639882d0b34109b5b3aec9", + "sha256:a7928283143a401e72a4fad43ecc85b35c27ae699cf5d54d39e1e72d97460e1d", + "sha256:adf4dd19d8875ac147bf926c727215a0faf21490b22c053db464e0bf0deb0485", + "sha256:ae8427a5e9062ba66fc2c62fb19a72276cf12c780e8db2b0956ea909c48acff5", + "sha256:b4c8b0bc5841e578d5fb32a16e0c305359b987b850a06964bd5a62739d688048", + "sha256:b84f29971f0ad4adaee391c6364e6f780d5aae7e9226d41964b26b49376071d0", + "sha256:c39c46d9e44447181cd502a35aad2bb178dbf1b1f86cf4db639d7b9614f837c6", + "sha256:cb2126603091902767d96bcb74093bd8b14982f41809f85c9b96e519c7e1dc41", + "sha256:dcef843f8de4e2ff5e35e96ec2a4abbdf403bd0f732ead127bd27e51f38ac298", + "sha256:e3447d9e074abf0e3cd85aef8131e01ab93f9f0e86654db7ac8a3f73c63706ce", + "sha256:f52010e0a44e3d8530437e7da38d11fb822acfb0d5b12e9cd5ba655509937ca0", + "sha256:f8196f739092a78e4f6b1b2172679ed3343c39c61a3e9d722ce6fcf1dac2824a" + ], + "markers": "python_version >= '3.6'", + "version": "==2.0.0" + }, "httptools": { "hashes": [ "sha256:0297822cea9f90a38df29f48e40b42ac3d48a28637368f3ec6d15eebefd182f9", @@ -636,34 +564,26 @@ }, "identify": { "hashes": [ - "sha256:f0faad595a4687053669c112004178149f6c326db71ee999ae4636685753ad2f", - "sha256:f7a93d6cf98e29bd07663c60728e7a4057615068d7a639d132dc883b2d54d31e" + "sha256:322a5699daecf7c6fd60e68852f36f2ecbb6a36ff6e6e973e0d2bb6fca203ee6", + "sha256:ef78c0d96098a3b5fe7720be4a97e73f439af7cf088ebf47b620aeaa10fadf97" ], "markers": "python_version >= '3.7'", - "version": "==2.5.22" + "version": "==2.5.5" }, "idna": { "hashes": [ "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" ], - "markers": "python_full_version >= '3.5.0'", + "markers": "python_version >= '3.5'", "version": "==3.4" }, "incremental": { "hashes": [ - "sha256:912feeb5e0f7e0188e6f42241d2f450002e11bbc0937c65865045854c24c0bd0", - "sha256:b864a1f30885ee72c5ac2835a761b8fe8aa9c28b9395cacf27286602688d3e51" + "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57", + "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321" ], - "version": "==22.10.0" - }, - "jinja2": { - "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" - ], - "index": "pypi", - "version": "==3.1.2" + "version": "==21.3.0" }, "jmespath": { "hashes": [ @@ -675,225 +595,144 @@ }, "jsonref": { "hashes": [ - "sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552", - "sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9" + "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f", + "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697" ], "index": "pypi", - "version": "==1.1.0" - }, - "jwcrypto": { - "hashes": [ - "sha256:80a35e9ed1b3b2c43ce03d92c5d48e6d0b6647e2aa2618e4963448923d78a37b" - ], - "markers": "python_version >= '3.6'", - "version": "==1.4.2" + "version": "==0.2" }, "lxml": { "hashes": [ - "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7", - "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726", - "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03", - "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140", - "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a", - "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05", - "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03", - "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419", - "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4", - "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e", - "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67", - "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50", - "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894", - "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf", - "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947", - "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1", - "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd", - "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3", - "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92", - "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3", - "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457", - "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74", - "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf", - "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1", - "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4", - "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975", - "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5", - "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe", - "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7", - "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1", - "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2", - "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409", - "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f", - "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f", - "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5", - "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24", - "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e", - "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4", - "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a", - "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c", - "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de", - "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f", - "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b", - "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5", - "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7", - "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a", - "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c", - "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9", - "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e", - "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab", - "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941", - "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5", - "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45", - "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7", - "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892", - "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746", - "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c", - "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53", - "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe", - "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184", - "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38", - "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df", - "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9", - "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b", - "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2", - "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0", - "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda", - "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b", - "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5", - "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380", - "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33", - "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8", - "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1", - "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889", - "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9", - "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f", - "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c" + "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318", + "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c", + "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b", + "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000", + "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73", + "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d", + "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb", + "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8", + "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2", + "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345", + "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94", + "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e", + "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b", + "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc", + "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a", + "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9", + "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc", + "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387", + "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb", + "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7", + "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4", + "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97", + "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67", + "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627", + "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7", + "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd", + "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3", + "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7", + "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130", + "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b", + "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036", + "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785", + "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca", + "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91", + "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc", + "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536", + "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391", + "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3", + "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d", + "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21", + "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3", + "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d", + "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29", + "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715", + "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed", + "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25", + "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c", + "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785", + "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837", + "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4", + "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b", + "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2", + "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067", + "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448", + "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d", + "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2", + "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc", + "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c", + "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5", + "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84", + "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8", + "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf", + "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7", + "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e", + "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb", + "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b", + "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3", + "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad", + "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8", + "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.9.2" - }, - "markupsafe": { - "hashes": [ - "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed", - "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc", - "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2", - "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460", - "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7", - "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0", - "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1", - "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa", - "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03", - "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323", - "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65", - "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013", - "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036", - "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f", - "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4", - "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419", - "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2", - "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619", - "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a", - "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a", - "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd", - "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7", - "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666", - "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65", - "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859", - "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625", - "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff", - "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156", - "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd", - "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba", - "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f", - "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1", - "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094", - "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a", - "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513", - "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed", - "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d", - "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3", - "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147", - "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c", - "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603", - "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601", - "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a", - "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1", - "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d", - "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3", - "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54", - "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2", - "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6", - "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.2" + "version": "==4.9.1" }, "msgpack": { "hashes": [ - "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164", - "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b", - "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c", - "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf", - "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd", - "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d", - "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c", - "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a", - "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e", - "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd", - "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025", - "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5", - "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705", - "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a", - "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d", - "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb", - "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11", - "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f", - "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c", - "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d", - "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea", - "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba", - "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87", - "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a", - "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c", - "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080", - "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198", - "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9", - "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a", - "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b", - "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f", - "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437", - "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f", - "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7", - "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2", - "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0", - "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48", - "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898", - "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0", - "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57", - "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8", - "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282", - "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1", - "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82", - "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc", - "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb", - "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6", - "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7", - "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9", - "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c", - "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1", - "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed", - "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c", - "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c", - "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77", - "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81", - "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a", - "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3", - "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086", - "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9", - "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f", - "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b", - "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d" - ], - "version": "==1.0.5" + "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467", + "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae", + "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92", + "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef", + "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624", + "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227", + "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88", + "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9", + "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8", + "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd", + "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6", + "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55", + "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e", + "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2", + "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44", + "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6", + "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9", + "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab", + "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae", + "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa", + "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9", + "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e", + "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250", + "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce", + "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075", + "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236", + "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae", + "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e", + "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f", + "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08", + "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6", + "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d", + "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43", + "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1", + "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6", + "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0", + "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c", + "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff", + "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db", + "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243", + "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661", + "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba", + "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e", + "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb", + "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52", + "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6", + "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1", + "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f", + "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da", + "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f", + "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c", + "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8" + ], + "version": "==1.0.4" }, "nodeenv": { "hashes": [ @@ -903,225 +742,170 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "version": "==1.7.0" }, - "numpy": { - "hashes": [ - "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187", - "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812", - "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7", - "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4", - "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6", - "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0", - "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4", - "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570", - "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4", - "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f", - "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80", - "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289", - "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385", - "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078", - "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c", - "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463", - "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3", - "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950", - "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155", - "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7", - "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c", - "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096", - "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17", - "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf", - "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4", - "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02", - "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c", - "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b" - ], - "index": "pypi", - "version": "==1.24.3" - }, "oauthlib": { "hashes": [ - "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", - "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" + "sha256:1565237372795bf6ee3e5aba5e2a85bd5a65d0e2aa5c628b9a97b7d7a0da3721", + "sha256:88e912ca1ad915e1dcc1c06fc9259d19de8deacd6fd17cc2df266decc2e49066" ], "markers": "python_version >= '3.6'", - "version": "==3.2.2" + "version": "==3.2.1" }, "openpyxl": { "hashes": [ - "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184", - "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5" + "sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355", + "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449" ], "markers": "python_version >= '3.6'", - "version": "==3.1.2" + "version": "==3.0.10" }, "packaging": { "hashes": [ - "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", - "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" - ], - "markers": "python_version >= '3.7'", - "version": "==23.1" - }, - "pandas": { - "hashes": [ - "sha256:0778ab54c8f399d83d98ffb674d11ec716449956bc6f6821891ab835848687f2", - "sha256:24472cfc7ced511ac90608728b88312be56edc8f19b9ed885a7d2e47ffaf69c0", - "sha256:2d1d138848dd71b37e3cbe7cd952ff84e2ab04d8988972166e18567dcc811245", - "sha256:3bb9d840bf15656805f6a3d87eea9dcb7efdf1314a82adcf7f00b820427c5570", - "sha256:425705cee8be54db2504e8dd2a730684790b15e5904b750c367611ede49098ab", - "sha256:4f3320bb55f34af4193020158ef8118ee0fb9aec7cc47d2084dbfdd868a0a24f", - "sha256:4ffb14f50c74ee541610668137830bb93e9dfa319b1bef2cedf2814cd5ac9c70", - "sha256:52c858de9e9fc422d25e67e1592a6e6135d7bcf9a19fcaf4d0831a0be496bf21", - "sha256:57c34b79c13249505e850d0377b722961b99140f81dafbe6f19ef10239f6284a", - "sha256:6ded51f7e3dd9b4f8b87f2ceb7bd1a8df2491f7ee72f7074c6927a512607199e", - "sha256:70db5c278bbec0306d32bf78751ff56b9594c05a5098386f6c8a563659124f91", - "sha256:78425ca12314b23356c28b16765639db10ebb7d8983f705d6759ff7fe41357fa", - "sha256:8318de0f886e4dcb8f9f36e45a3d6a6c3d1cfdc508354da85e739090f0222991", - "sha256:8f987ec26e96a8490909bc5d98c514147236e49830cba7df8690f6087c12bbae", - "sha256:9253edfd015520ce77a9343eb7097429479c039cd3ebe81d7810ea11b4b24695", - "sha256:977326039bd1ded620001a1889e2ed4798460a6bc5a24fbaebb5f07a41c32a55", - "sha256:a4f789b7c012a608c08cda4ff0872fd979cb18907a37982abe884e6f529b8793", - "sha256:b3ba8f5dd470d8bfbc4259829589f4a32881151c49e36384d9eb982b35a12020", - "sha256:b5337c87c4e963f97becb1217965b6b75c6fe5f54c4cf09b9a5ac52fc0bd03d3", - "sha256:bbb2c5e94d6aa4e632646a3bacd05c2a871c3aa3e85c9bec9be99cb1267279f2", - "sha256:c24c7d12d033a372a9daf9ff2c80f8b0af6f98d14664dbb0a4f6a029094928a7", - "sha256:cda9789e61b44463c1c4fe17ef755de77bcd13b09ba31c940d20f193d63a5dc8", - "sha256:d08e41d96bc4de6f500afe80936c68fce6099d5a434e2af7c7fd8e7c72a3265d", - "sha256:d93b7fcfd9f3328072b250d6d001dcfeec5d3bb66c1b9c8941e109a46c0c01a8", - "sha256:fcd471c9d9f60926ab2f15c6c29164112f458acb42280365fbefa542d0c2fc74" + "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", + "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" ], - "index": "pypi", - "version": "==2.0.0" + "markers": "python_version >= '3.6'", + "version": "==21.3" }, "phonenumbers": { "hashes": [ - "sha256:421b69fd6d6650372000a6c47ab5b5c5d7b438b33f7b317739e728eff1ec1886", - "sha256:fe071b8324473e72a54b52e602d059c15b999ec9900fff9e42c01b422aeca662" + "sha256:80a7422cf0999a6f9b7a2e6cfbdbbfcc56ab5b75414dc3b805bbec91276b64a3", + "sha256:82a4f226c930d02dcdf6d4b29e4cfd8678991fe65c2efd5fdd143557186f0868" ], "index": "pypi", - "version": "==8.13.10" + "version": "==8.12.56" }, "pillow": { "hashes": [ - "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1", - "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba", - "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a", - "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799", - "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51", - "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb", - "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5", - "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270", - "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6", - "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47", - "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf", - "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e", - "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b", - "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66", - "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865", - "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec", - "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c", - "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1", - "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38", - "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906", - "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705", - "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef", - "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc", - "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f", - "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf", - "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392", - "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d", - "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe", - "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32", - "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5", - "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7", - "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44", - "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d", - "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3", - "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625", - "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e", - "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829", - "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089", - "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3", - "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78", - "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96", - "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964", - "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597", - "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99", - "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a", - "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140", - "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7", - "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16", - "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903", - "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1", - "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296", - "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572", - "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115", - "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a", - "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd", - "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4", - "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1", - "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb", - "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa", - "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a", - "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569", - "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c", - "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf", - "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082", - "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062", - "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579" + "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927", + "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14", + "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc", + "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58", + "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60", + "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76", + "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c", + "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac", + "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490", + "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1", + "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f", + "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d", + "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f", + "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069", + "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402", + "sha256:336b9036127eab855beec9662ac3ea13a4544a523ae273cbf108b228ecac8437", + "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885", + "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e", + "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be", + "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff", + "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da", + "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004", + "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f", + "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20", + "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d", + "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c", + "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544", + "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3", + "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04", + "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c", + "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5", + "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4", + "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb", + "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4", + "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c", + "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467", + "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e", + "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421", + "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b", + "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8", + "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb", + "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3", + "sha256:adabc0bce035467fb537ef3e5e74f2847c8af217ee0be0455d4fec8adc0462fc", + "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf", + "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1", + "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a", + "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28", + "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0", + "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1", + "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8", + "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd", + "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4", + "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8", + "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f", + "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013", + "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59", + "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc", + "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4" ], "index": "pypi", - "version": "==9.5.0" + "version": "==9.2.0" }, "platformdirs": { "hashes": [ - "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08", - "sha256:ebe11c0d7a805086e99506aa331612429a72ca7cd52a1f0d277dc4adc20cb10e" + "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788", + "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19" ], "markers": "python_version >= '3.7'", - "version": "==3.2.0" + "version": "==2.5.2" }, "pre-commit": { "hashes": [ - "sha256:0b4210aea813fe81144e87c5a291f09ea66f199f367fa1df41b55e1d26e1e2b4", - "sha256:5b808fcbda4afbccf6d6633a56663fed35b6c2bc08096fd3d47ce197ac351d9d" + "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7", + "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959" ], "index": "pypi", - "version": "==3.2.2" + "version": "==2.20.0" }, "psycopg2": { "hashes": [ - "sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744", - "sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f", - "sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214", - "sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39", - "sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad", - "sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889", - "sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258", - "sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7", - "sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394", - "sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5", - "sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011", - "sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494", - "sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1" + "sha256:06f32425949bd5fe8f625c49f17ebb9784e1e4fe928b7cce72edc36fb68e4c0c", + "sha256:0762c27d018edbcb2d34d51596e4346c983bd27c330218c56c4dc25ef7e819bf", + "sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362", + "sha256:34b33e0162cfcaad151f249c2649fd1030010c16f4bbc40a604c1cb77173dcf7", + "sha256:4295093a6ae3434d33ec6baab4ca5512a5082cc43c0505293087b8a46d108461", + "sha256:8cf3878353cc04b053822896bc4922b194792df9df2f1ad8da01fb3043602126", + "sha256:8e841d1bf3434da985cc5ef13e6f75c8981ced601fd70cc6bf33351b91562981", + "sha256:9572e08b50aed176ef6d66f15a21d823bb6f6d23152d35e8451d7d2d18fdac56", + "sha256:a81e3866f99382dfe8c15a151f1ca5fde5815fde879348fe5a9884a7c092a305", + "sha256:cb10d44e6694d763fa1078a26f7f6137d69f555a78ec85dc2ef716c37447e4b2", + "sha256:d3ca6421b942f60c008f81a3541e8faf6865a28d5a9b48544b0ee4f40cac7fca" ], "index": "pypi", - "version": "==2.9.6" + "version": "==2.9.3" }, "pyasn1": { "hashes": [ - "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57", - "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.5.0" + "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359", + "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576", + "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf", + "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7", + "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d", + "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00", + "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8", + "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86", + "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12", + "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776", + "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba", + "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2", + "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3" + ], + "version": "==0.4.8" }, "pyasn1-modules": { "hashes": [ - "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c", - "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==0.3.0" + "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8", + "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199", + "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811", + "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed", + "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4", + "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e", + "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74", + "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb", + "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45", + "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd", + "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0", + "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d", + "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405" + ], + "version": "==0.2.8" }, "pycparser": { "hashes": [ @@ -1133,26 +917,27 @@ }, "pyjwt": { "hashes": [ - "sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd", - "sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14" + "sha256:8d82e7087868e94dd8d7d418e5088ce64f7daab4b36db654cbaedb46f9d1ca80", + "sha256:e77ab89480905d86998442ac5788f35333fa85f65047a534adc38edf3c88fc3b" ], "markers": "python_version >= '3.7'", - "version": "==2.6.0" + "version": "==2.5.0" }, "pyopenssl": { "hashes": [ - "sha256:841498b9bec61623b1b6c47ebbc02367c07d60e0e195f19790817f10cc8db0b7", - "sha256:9e0c526404a210df9d2b18cd33364beadb0dc858a739b885677bc65e105d4a4c" + "sha256:7a83b7b272dd595222d672f5ce29aa030f1fb837630ef229f62e72e395ce8968", + "sha256:b28437c9773bb6c6958628cf9c3bebe585de661dba6f63df17111966363dd15e" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==23.1.1" + "version": "==22.1.0" }, - "pypng": { + "pyparsing": { "hashes": [ - "sha256:4a43e969b8f5aaafb2a415536c1a8ec7e341cd6a3f957fd5b5f32a4cfeed902c", - "sha256:739c433ba96f078315de54c0db975aee537cbc3e1d0ae4ed9aab0ca1e427e2c1" + "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", + "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" ], - "version": "==0.20220715.0" + "markers": "python_full_version >= '3.6.8'", + "version": "==3.0.9" }, "python-dateutil": { "hashes": [ @@ -1164,10 +949,10 @@ }, "python-dotenv": { "hashes": [ - "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba", - "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a" + "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5", + "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045" ], - "version": "==1.0.0" + "version": "==0.21.0" }, "python3-openid": { "hashes": [ @@ -1179,10 +964,10 @@ }, "pytz": { "hashes": [ - "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588", - "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb" + "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197", + "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5" ], - "version": "==2023.3" + "version": "==2022.2.1" }, "pyyaml": { "hashes": [ @@ -1232,27 +1017,26 @@ }, "qrcode": { "hashes": [ - "sha256:581dca7a029bcb2deef5d01068e39093e80ef00b4a61098a2182eac59d01643a", - "sha256:9dd969454827e127dbd93696b20747239e6d540e082937c90f14ac95b30f5845" + "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578" ], "index": "pypi", - "version": "==7.4.2" + "version": "==7.3.1" }, "redis": { "hashes": [ - "sha256:2c19e6767c474f2e85167909061d525ed65bea9301c0770bb151e041b7ac89a2", - "sha256:73ec35da4da267d6847e47f68730fdd5f62e2ca69e3ef5885c6a78a9374c3893" + "sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54", + "sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880" ], - "markers": "python_version >= '3.7'", - "version": "==4.5.4" + "markers": "python_version >= '3.6'", + "version": "==4.3.4" }, "requests": { "hashes": [ - "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa", - "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf" + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], - "markers": "python_version >= '3.7' and python_version < '4.0'", - "version": "==2.28.2" + "markers": "python_version >= '3.7' and python_version < '4'", + "version": "==2.28.1" }, "requests-oauthlib": { "hashes": [ @@ -1272,11 +1056,11 @@ }, "sentry-sdk": { "hashes": [ - "sha256:0ad6bbbe78057b8031a07de7aca6d2a83234e51adc4d436eaf8d8c697184db71", - "sha256:a3410381ae769a436c0852cce140a5e5e49f566a07fb7c2ab445af1302f6ad89" + "sha256:d6c71d2f85710b66822adaa954af7912bab135d6c85febd5b0f3dfd4ab37e181", + "sha256:ef925b5338625448645a778428d8f22a3d17de8b28cc8e6fba60b93393ad86fe" ], "index": "pypi", - "version": "==1.20.0" + "version": "==1.9.9" }, "service-identity": { "hashes": [ @@ -1287,11 +1071,11 @@ }, "setuptools": { "hashes": [ - "sha256:6f0839fbdb7e3cfef1fc38d7954f5c1c26bf4eebb155a55c9bf8faf997b9fb67", - "sha256:bb16732e8eb928922eabaa022f881ae2b7cdcfaf9993ef1f5e841a96d32b8e0c" + "sha256:1b6bdc6161661409c5f21508763dc63ab20a9ac2f8ba20029aaaa7fdb9118012", + "sha256:3050e338e5871e70c72983072fe34f6032ae1cdeeeb67338199c2f74e083a80e" ], "markers": "python_version >= '3.7'", - "version": "==67.7.1" + "version": "==65.4.1" }, "six": { "hashes": [ @@ -1311,35 +1095,35 @@ }, "social-auth-app-django": { "hashes": [ - "sha256:0347ca4cd23ea9d15a665da9d22950552fb66b95600e6c2ebae38ca883b3a4ed", - "sha256:4a5dae406f3874b4003708ff120c02cb1a4c8eeead56cd163646347309fcd0f8" + "sha256:52241a25445a010ab1c108bafff21fc5522d5c8cd0d48a92c39c7371824b065d", + "sha256:b6e3132ce087cdd6e1707aeb1b588be41d318408fcf6395435da0bc6fe9a9795" ], "index": "pypi", - "version": "==5.2.0" + "version": "==5.0.0" }, "social-auth-core": { "hashes": [ - "sha256:9791d7c7aee2ac8517fe7a2ea2f942a8a5492b3a4ccb44a9b0dacc87d182f2aa", - "sha256:ea7a19c46b791b767e95f467881b53c5fd0d1efb40048d9ed3dbc46daa05c954" + "sha256:1e3440d104f743b02dfe258c9d4dba5b4065abf24b2f7eb362b47054d21797df", + "sha256:4686f0e43cf12954216875a32e944847bb1dc69e7cd9573d16a9003bb05ca477" ], "markers": "python_version >= '3.6'", - "version": "==4.4.2" + "version": "==4.3.0" }, "soupsieve": { "hashes": [ - "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8", - "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea" + "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", + "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d" ], - "markers": "python_version >= '3.7'", - "version": "==2.4.1" + "markers": "python_version >= '3.6'", + "version": "==2.3.2.post1" }, "sqlparse": { "hashes": [ - "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", - "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" + "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34", + "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268" ], - "markers": "python_full_version >= '3.5.0'", - "version": "==0.4.4" + "markers": "python_version >= '3.5'", + "version": "==0.4.3" }, "tatsu": { "hashes": [ @@ -1357,40 +1141,40 @@ "index": "pypi", "version": "==1.7.0" }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==0.10.2" + }, "twisted": { "extras": [ "tls" ], "hashes": [ - "sha256:32acbd40a94f5f46e7b42c109bfae2b302250945561783a8b7a059048f2d4d31", - "sha256:86c55f712cc5ab6f6d64e02503352464f0400f66d4f079096d744080afcccbd0" + "sha256:8d4718d1e48dcc28933f8beb48dc71cfe77a125e37ad1eb7a3d0acc49baf6c99", + "sha256:e5b60de39f2d1da153fbe1874d885fe3fcbdb21fcc446fa759a53e8fc3513bed" ], "markers": "python_full_version >= '3.7.1'", - "version": "==22.10.0" + "version": "==22.8.0" }, "txaio": { "hashes": [ - "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490", - "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704" + "sha256:2e4582b70f04b2345908254684a984206c0d9b50e3074a24a4c55aba21d24d01", + "sha256:41223af4a9d5726e645a8ee82480f413e5e300dd257db94bc38ae12ea48fb2e5" ], - "markers": "python_version >= '3.7'", - "version": "==23.1.1" + "markers": "python_version >= '3.6'", + "version": "==22.2.1" }, "typing-extensions": { "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02", + "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6" ], "markers": "python_version >= '3.7'", - "version": "==4.5.0" - }, - "tzdata": { - "hashes": [ - "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a", - "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda" - ], - "markers": "python_version >= '2'", - "version": "==2023.3" + "version": "==4.3.0" }, "unittest-xml-reporting": { "hashes": [ @@ -1410,38 +1194,38 @@ }, "uritools": { "hashes": [ - "sha256:d122d394ed6e6e15ac0fddba6a5b19e9fa204e7797507815cbfb0e1455ac0475", - "sha256:efc5c3a6de05404850685a8d3f34da8476b56aa3516fbf8eff5c8704c7a2826f" + "sha256:420d94c1ff4bf90c678fca9c17b8314243bbcaa992c400a95e327f7f622e1edf", + "sha256:9a5a1495c55072093216f79931ca45fd81b59208aa64caae50ab68333514f97e" ], "markers": "python_version ~= '3.7'", - "version": "==4.0.1" + "version": "==4.0.0" }, "urlextract": { "hashes": [ - "sha256:3573f6b812814efe06ca46e91e82d984edaa3cd07daaaaa296a467ad9881a037", - "sha256:98b38aca4a555116e8b46e5a134b9e4e54e351b8e37169d2857730d1d0ce42c7" + "sha256:574f0d8c562d377336a5154840c7e4eecf54c102a538971c897f7313075a8887", + "sha256:c22a9645cae1e1390cc512fd4f4d1f37b72538eecfdc3365905a2e616e7b6b88" ], "index": "pypi", - "version": "==1.8.0" + "version": "==1.6.0" }, "urllib3": { "hashes": [ - "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305", - "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42" + "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", + "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" ], "markers": "python_version >= '3.6'", - "version": "==1.26.15" + "version": "==1.26.12" }, "uvicorn": { "extras": [ "standard" ], "hashes": [ - "sha256:0fac9cb342ba099e0d582966005f3fdba5b0290579fed4a6266dc702ca7bb032", - "sha256:e47cac98a6da10cd41e6fd036d472c6f58ede6c5dbee3dbee3ef7a100ed97742" + "sha256:0abd429ebb41e604ed8d2be6c60530de3408f250e8d2d84967d85ba9e86fe3af", + "sha256:9a66e7c42a2a95222f76ec24a4b754c158261c4696e683b9dadc72b590e0311b" ], "index": "pypi", - "version": "==0.21.1" + "version": "==0.18.3" }, "uvloop": { "hashes": [ @@ -1481,45 +1265,41 @@ }, "uwsgi": { "hashes": [ - "sha256:35a30d83791329429bc04fe44183ce4ab512fcf6968070a7bfba42fc5a0552a9" + "sha256:88ab9867d8973d8ae84719cf233b7dafc54326fcaec89683c3f9f77c002cdff9" ], "markers": "sys_platform == 'linux'", - "version": "==2.0.21" + "version": "==2.0.20" }, "virtualenv": { "hashes": [ - "sha256:278753c47aaef1a0f14e6db8a4c5e1e040e90aea654d0fc1dc7e0d8a42616cc3", - "sha256:48fd3b907b5149c5aab7c23d9790bea4cac6bc6b150af8635febc4cfeab1275a" + "sha256:227ea1b9994fdc5ea31977ba3383ef296d7472ea85be9d6732e42a91c04e80da", + "sha256:d07dfc5df5e4e0dbc92862350ad87a36ed505b978f6c39609dc489eadd5b0d27" ], - "markers": "python_version >= '3.7'", - "version": "==20.22.0" + "markers": "python_version >= '3.6'", + "version": "==20.16.5" }, "watchfiles": { "hashes": [ - "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911", - "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda", - "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154", - "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af", - "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d", - "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c", - "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48", - "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c", - "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545", - "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e", - "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120", - "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7", - "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8", - "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc", - "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056", - "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193", - "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3", - "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf", - "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79", - "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1", - "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b", - "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0" - ], - "version": "==0.19.0" + "sha256:00e5f307a58752ec1478eeb738863544bde21cc7a2728bd1c216060406bde9c1", + "sha256:1dd1e3181ad5d83ca35e9147c72e24f39437fcdf570c9cdc532016399fb62957", + "sha256:204950f1d6083539af5c8b7d4f5f8039c3ce36fa692da12d9743448f3199cb15", + "sha256:4056398d8f6d4972fe0918707b59d4cb84470c91d3c37f0e11e5a66c2a598760", + "sha256:539bcdb55a487126776c9d8c011094214d1df3f9a2321a6c0b1583197309405a", + "sha256:53a2faeb121bc51bb6b960984f46901227e2e2475acc5a8d4c905a600436752d", + "sha256:58dc3140dcf02a8aa76464a77a093016f10e89306fec21a4814922a64f3e8b9f", + "sha256:6a3d6c699f3ce238dfa90bcef501f331a69b0d9b076f14459ed8eab26ba2f4cf", + "sha256:92675f379a9d5adbc6a52179f3e39aa56944c6eecb80384608fff2ed2619103a", + "sha256:a53cb6c06e5c1f216c792fbb432ce315239d432cb8b68d508547100939ec0399", + "sha256:a7f4271af86569bdbf131dd5c7c121c45d0ed194f3c88b88326e48a3b6a2db12", + "sha256:ad2bdcae4c0f07ca6c090f5a2c30188cc6edba011b45e7c96eb1896648092367", + "sha256:adcf15ecc2182ea9d2358c1a8c2b53203c3909484918776929b7bbe205522c0e", + "sha256:ae7c57ef920589a40270d5ef3216d693f4e6f8864d8fc8b6cb7885ca98ad2a61", + "sha256:afd35a1bd3b9e68efe384ae7538481ae725597feb66f56f4bd23ecdbda726da0", + "sha256:b5c334cd3bc88aa4a8a1e08ec9f702b63c947211275defdc2dd79dc037fcb500", + "sha256:c7e1ffbd03cbcb46d1b7833e10e7d6b678ab083b4e4b80db06cfff5baca3c93f", + "sha256:ffff3418dc753a2aed2d00200a4daeaac295c40458f8012836a65555f288be8b" + ], + "version": "==0.17.0" }, "webencodings": { "hashes": [ @@ -1530,195 +1310,183 @@ }, "websockets": { "hashes": [ - "sha256:0fb4480556825e4e6bf2eebdbeb130d9474c62705100c90e59f2f56459ddab42", - "sha256:13bd5bebcd16a4b5e403061b8b9dcc5c77e7a71e3c57e072d8dff23e33f70fba", - "sha256:143782041e95b63083b02107f31cda999f392903ae331de1307441f3a4557d51", - "sha256:1b52def56d2a26e0e9c464f90cadb7e628e04f67b0ff3a76a4d9a18dfc35e3dd", - "sha256:1df2413266bf48430ef2a752c49b93086c6bf192d708e4a9920544c74cd2baa6", - "sha256:2174a75d579d811279855df5824676d851a69f52852edb0e7551e0eeac6f59a4", - "sha256:220d5b93764dd70d7617f1663da64256df7e7ea31fc66bc52c0e3750ee134ae3", - "sha256:232b6ba974f5d09b1b747ac232f3a3d8f86de401d7b565e837cc86988edf37ac", - "sha256:25aae96c1060e85836552a113495db6d857400288161299d77b7b20f2ac569f2", - "sha256:25e265686ea385f22a00cc2b719b880797cd1bb53b46dbde969e554fb458bfde", - "sha256:2abeeae63154b7f63d9f764685b2d299e9141171b8b896688bd8baec6b3e2303", - "sha256:2acdc82099999e44fa7bd8c886f03c70a22b1d53ae74252f389be30d64fd6004", - "sha256:2eb042734e710d39e9bc58deab23a65bd2750e161436101488f8af92f183c239", - "sha256:3178d965ec204773ab67985a09f5696ca6c3869afeed0bb51703ea404a24e975", - "sha256:320ddceefd2364d4afe6576195201a3632a6f2e6d207b0c01333e965b22dbc84", - "sha256:34a6f8996964ccaa40da42ee36aa1572adcb1e213665e24aa2f1037da6080909", - "sha256:3565a8f8c7bdde7c29ebe46146bd191290413ee6f8e94cf350609720c075b0a1", - "sha256:392d409178db1e46d1055e51cc850136d302434e12d412a555e5291ab810f622", - "sha256:3a09cce3dacb6ad638fdfa3154d9e54a98efe7c8f68f000e55ca9c716496ca67", - "sha256:3a2100b02d1aaf66dc48ff1b2a72f34f6ebc575a02bc0350cc8e9fbb35940166", - "sha256:3b87cd302f08ea9e74fdc080470eddbed1e165113c1823fb3ee6328bc40ca1d3", - "sha256:3e79065ff6549dd3c765e7916067e12a9c91df2affea0ac51bcd302aaf7ad207", - "sha256:3ffe251a31f37e65b9b9aca5d2d67fd091c234e530f13d9dce4a67959d5a3fba", - "sha256:46388a050d9e40316e58a3f0838c63caacb72f94129eb621a659a6e49bad27ce", - "sha256:46dda4bc2030c335abe192b94e98686615f9274f6b56f32f2dd661fb303d9d12", - "sha256:4c54086b2d2aec3c3cb887ad97e9c02c6be9f1d48381c7419a4aa932d31661e4", - "sha256:5004c087d17251938a52cce21b3dbdabeecbbe432ce3f5bbbf15d8692c36eac9", - "sha256:502683c5dedfc94b9f0f6790efb26aa0591526e8403ad443dce922cd6c0ec83b", - "sha256:518ed6782d9916c5721ebd61bb7651d244178b74399028302c8617d0620af291", - "sha256:580cc95c58118f8c39106be71e24d0b7e1ad11a155f40a2ee687f99b3e5e432e", - "sha256:58477b041099bb504e1a5ddd8aa86302ed1d5c6995bdd3db2b3084ef0135d277", - "sha256:5875f623a10b9ba154cb61967f940ab469039f0b5e61c80dd153a65f024d9fb7", - "sha256:5c7de298371d913824f71b30f7685bb07ad13969c79679cca5b1f7f94fec012f", - "sha256:634239bc844131863762865b75211a913c536817c0da27f691400d49d256df1d", - "sha256:6d872c972c87c393e6a49c1afbdc596432df8c06d0ff7cd05aa18e885e7cfb7c", - "sha256:752fbf420c71416fb1472fec1b4cb8631c1aa2be7149e0a5ba7e5771d75d2bb9", - "sha256:7742cd4524622cc7aa71734b51294644492a961243c4fe67874971c4d3045982", - "sha256:808b8a33c961bbd6d33c55908f7c137569b09ea7dd024bce969969aa04ecf07c", - "sha256:87c69f50281126dcdaccd64d951fb57fbce272578d24efc59bce72cf264725d0", - "sha256:8df63dcd955eb6b2e371d95aacf8b7c535e482192cff1b6ce927d8f43fb4f552", - "sha256:8f24cd758cbe1607a91b720537685b64e4d39415649cac9177cd1257317cf30c", - "sha256:8f392587eb2767afa8a34e909f2fec779f90b630622adc95d8b5e26ea8823cb8", - "sha256:954eb789c960fa5daaed3cfe336abc066941a5d456ff6be8f0e03dd89886bb4c", - "sha256:955fcdb304833df2e172ce2492b7b47b4aab5dcc035a10e093d911a1916f2c87", - "sha256:95c09427c1c57206fe04277bf871b396476d5a8857fa1b99703283ee497c7a5d", - "sha256:a4fe2442091ff71dee0769a10449420fd5d3b606c590f78dd2b97d94b7455640", - "sha256:aa7b33c1fb2f7b7b9820f93a5d61ffd47f5a91711bc5fa4583bbe0c0601ec0b2", - "sha256:adf6385f677ed2e0b021845b36f55c43f171dab3a9ee0ace94da67302f1bc364", - "sha256:b1a69701eb98ed83dd099de4a686dc892c413d974fa31602bc00aca7cb988ac9", - "sha256:b2a573c8d71b7af937852b61e7ccb37151d719974146b5dc734aad350ef55a02", - "sha256:b444366b605d2885f0034dd889faf91b4b47668dd125591e2c64bfde611ac7e1", - "sha256:b985ba2b9e972cf99ddffc07df1a314b893095f62c75bc7c5354a9c4647c6503", - "sha256:c78ca3037a954a4209b9f900e0eabbc471fb4ebe96914016281df2c974a93e3e", - "sha256:ca9b2dced5cbbc5094678cc1ec62160f7b0fe4defd601cd28a36fde7ee71bbb5", - "sha256:cb46d2c7631b2e6f10f7c8bac7854f7c5e5288f024f1c137d4633c79ead1e3c0", - "sha256:ce69f5c742eefd039dce8622e99d811ef2135b69d10f9aa79fbf2fdcc1e56cd7", - "sha256:cf45d273202b0c1cec0f03a7972c655b93611f2e996669667414557230a87b88", - "sha256:d1881518b488a920434a271a6e8a5c9481a67c4f6352ebbdd249b789c0467ddc", - "sha256:d3cc3e48b6c9f7df8c3798004b9c4b92abca09eeea5e1b0a39698f05b7a33b9d", - "sha256:d6b2bfa1d884c254b841b0ff79373b6b80779088df6704f034858e4d705a4802", - "sha256:d70a438ef2a22a581d65ad7648e949d4ccd20e3c8ed7a90bbc46df4e60320891", - "sha256:daa1e8ea47507555ed7a34f8b49398d33dff5b8548eae3de1dc0ef0607273a33", - "sha256:dca9708eea9f9ed300394d4775beb2667288e998eb6f542cdb6c02027430c599", - "sha256:dd906b0cdc417ea7a5f13bb3c6ca3b5fd563338dc596996cb0fdd7872d691c0a", - "sha256:e0eeeea3b01c97fd3b5049a46c908823f68b59bf0e18d79b231d8d6764bc81ee", - "sha256:e37a76ccd483a6457580077d43bc3dfe1fd784ecb2151fcb9d1c73f424deaeba", - "sha256:e8b967a4849db6b567dec3f7dd5d97b15ce653e3497b8ce0814e470d5e074750", - "sha256:ec00401846569aaf018700249996143f567d50050c5b7b650148989f956547af", - "sha256:ede13a6998ba2568b21825809d96e69a38dc43184bdeebbde3699c8baa21d015", - "sha256:f97e03d4d5a4f0dca739ea274be9092822f7430b77d25aa02da6775e490f6846" - ], - "version": "==11.0.2" + "sha256:07cdc0a5b2549bcfbadb585ad8471ebdc7bdf91e32e34ae3889001c1c106a6af", + "sha256:210aad7fdd381c52e58777560860c7e6110b6174488ef1d4b681c08b68bf7f8c", + "sha256:28dd20b938a57c3124028680dc1600c197294da5db4292c76a0b48efb3ed7f76", + "sha256:2f94fa3ae454a63ea3a19f73b95deeebc9f02ba2d5617ca16f0bbdae375cda47", + "sha256:31564a67c3e4005f27815634343df688b25705cccb22bc1db621c781ddc64c69", + "sha256:347974105bbd4ea068106ec65e8e8ebd86f28c19e529d115d89bd8cc5cda3079", + "sha256:379e03422178436af4f3abe0aa8f401aa77ae2487843738542a75faf44a31f0c", + "sha256:3eda1cb7e9da1b22588cefff09f0951771d6ee9fa8dbe66f5ae04cc5f26b2b55", + "sha256:51695d3b199cd03098ae5b42833006a0f43dc5418d3102972addc593a783bc02", + "sha256:54c000abeaff6d8771a4e2cef40900919908ea7b6b6a30eae72752607c6db559", + "sha256:5b936bf552e4f6357f5727579072ff1e1324717902127ffe60c92d29b67b7be3", + "sha256:6075fd24df23133c1b078e08a9b04a3bc40b31a8def4ee0b9f2c8865acce913e", + "sha256:661f641b44ed315556a2fa630239adfd77bd1b11cb0b9d96ed8ad90b0b1e4978", + "sha256:6ea6b300a6bdd782e49922d690e11c3669828fe36fc2471408c58b93b5535a98", + "sha256:6ed1d6f791eabfd9808afea1e068f5e59418e55721db8b7f3bfc39dc831c42ae", + "sha256:7934e055fd5cd9dee60f11d16c8d79c4567315824bacb1246d0208a47eca9755", + "sha256:7ab36e17af592eec5747c68ef2722a74c1a4a70f3772bc661079baf4ae30e40d", + "sha256:7f6d96fdb0975044fdd7953b35d003b03f9e2bcf85f2d2cf86285ece53e9f991", + "sha256:83e5ca0d5b743cde3d29fda74ccab37bdd0911f25bd4cdf09ff8b51b7b4f2fa1", + "sha256:85506b3328a9e083cc0a0fb3ba27e33c8db78341b3eb12eb72e8afd166c36680", + "sha256:8af75085b4bc0b5c40c4a3c0e113fa95e84c60f4ed6786cbb675aeb1ee128247", + "sha256:8b1359aba0ff810d5830d5ab8e2c4a02bebf98a60aa0124fb29aa78cfdb8031f", + "sha256:8fbd7d77f8aba46d43245e86dd91a8970eac4fb74c473f8e30e9c07581f852b2", + "sha256:907e8247480f287aa9bbc9391bd6de23c906d48af54c8c421df84655eef66af7", + "sha256:93d5ea0b5da8d66d868b32c614d2b52d14304444e39e13a59566d4acb8d6e2e4", + "sha256:97bc9d41e69a7521a358f9b8e44871f6cdeb42af31815c17aed36372d4eec667", + "sha256:994cdb1942a7a4c2e10098d9162948c9e7b235df755de91ca33f6e0481366fdb", + "sha256:a141de3d5a92188234afa61653ed0bbd2dde46ad47b15c3042ffb89548e77094", + "sha256:a1e15b230c3613e8ea82c9fc6941b2093e8eb939dd794c02754d33980ba81e36", + "sha256:aad5e300ab32036eb3fdc350ad30877210e2f51bceaca83fb7fef4d2b6c72b79", + "sha256:b529fdfa881b69fe563dbd98acce84f3e5a67df13de415e143ef053ff006d500", + "sha256:b9c77f0d1436ea4b4dc089ed8335fa141e6a251a92f75f675056dac4ab47a71e", + "sha256:bb621ec2dbbbe8df78a27dbd9dd7919f9b7d32a73fafcb4d9252fc4637343582", + "sha256:c7250848ce69559756ad0086a37b82c986cd33c2d344ab87fea596c5ac6d9442", + "sha256:c8d1d14aa0f600b5be363077b621b1b4d1eb3fbf90af83f9281cda668e6ff7fd", + "sha256:d1655a6fc7aecd333b079d00fb3c8132d18988e47f19740c69303bf02e9883c6", + "sha256:d6353ba89cfc657a3f5beabb3b69be226adbb5c6c7a66398e17809b0ce3c4731", + "sha256:da4377904a3379f0c1b75a965fff23b28315bcd516d27f99a803720dfebd94d4", + "sha256:e49ea4c1a9543d2bd8a747ff24411509c29e4bdcde05b5b0895e2120cb1a761d", + "sha256:e4e08305bfd76ba8edab08dcc6496f40674f44eb9d5e23153efa0a35750337e8", + "sha256:e6fa05a680e35d0fcc1470cb070b10e6fe247af54768f488ed93542e71339d6f", + "sha256:e7e6f2d6fd48422071cc8a6f8542016f350b79cc782752de531577d35e9bd677", + "sha256:e904c0381c014b914136c492c8fa711ca4cced4e9b3d110e5e7d436d0fc289e8", + "sha256:ec2b0ab7edc8cd4b0eb428b38ed89079bdc20c6bdb5f889d353011038caac2f9", + "sha256:ef5ce841e102278c1c2e98f043db99d6755b1c58bde475516aef3a008ed7f28e", + "sha256:f351c7d7d92f67c0609329ab2735eee0426a03022771b00102816a72715bb00b", + "sha256:fab7c640815812ed5f10fbee7abbf58788d602046b7bb3af9b1ac753a6d5e916", + "sha256:fc06cc8073c8e87072138ba1e431300e2d408f054b27047d047b549455066ff4" + ], + "version": "==10.3" }, "wrapt": { "hashes": [ - "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0", - "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420", - "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a", - "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c", - "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079", - "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923", - "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f", - "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1", - "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8", - "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86", - "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0", - "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364", - "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e", - "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c", - "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e", - "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c", - "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727", - "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff", - "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e", - "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29", - "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7", - "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72", - "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475", - "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a", - "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317", - "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2", - "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd", - "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640", - "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98", - "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248", - "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e", - "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d", - "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec", - "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1", - "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e", - "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9", - "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92", - "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb", - "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094", - "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46", - "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29", - "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd", - "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705", - "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8", - "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975", - "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb", - "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e", - "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b", - "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418", - "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019", - "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1", - "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba", - "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6", - "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2", - "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3", - "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7", - "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752", - "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416", - "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f", - "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1", - "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc", - "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145", - "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee", - "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a", - "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7", - "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b", - "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653", - "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0", - "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90", - "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29", - "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6", - "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034", - "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09", - "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559", - "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639" + "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3", + "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b", + "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4", + "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2", + "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656", + "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3", + "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff", + "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310", + "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a", + "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57", + "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069", + "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383", + "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe", + "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87", + "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d", + "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b", + "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907", + "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f", + "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0", + "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28", + "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1", + "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853", + "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc", + "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3", + "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3", + "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164", + "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1", + "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c", + "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1", + "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7", + "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1", + "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320", + "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed", + "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1", + "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248", + "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c", + "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456", + "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77", + "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef", + "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1", + "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7", + "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86", + "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4", + "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d", + "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d", + "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8", + "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5", + "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471", + "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00", + "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68", + "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3", + "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d", + "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735", + "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d", + "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569", + "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7", + "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59", + "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5", + "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb", + "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b", + "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f", + "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462", + "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015", + "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.15.0" + "version": "==1.14.1" }, "zope.interface": { "hashes": [ - "sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373", - "sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb", - "sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446", - "sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8", - "sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c", - "sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8", - "sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2", - "sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f", - "sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f", - "sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5", - "sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85", - "sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc", - "sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788", - "sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518", - "sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410", - "sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464", - "sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5", - "sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d", - "sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52", - "sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca", - "sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8", - "sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2", - "sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f", - "sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58", - "sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a", - "sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d", - "sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28", - "sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990", - "sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995", - "sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30" + "sha256:08f9636e99a9d5410181ba0729e0408d3d8748026ea938f3b970a0249daa8192", + "sha256:0b465ae0962d49c68aa9733ba92a001b2a0933c317780435f00be7ecb959c702", + "sha256:0cba8477e300d64a11a9789ed40ee8932b59f9ee05f85276dbb4b59acee5dd09", + "sha256:0cee5187b60ed26d56eb2960136288ce91bcf61e2a9405660d271d1f122a69a4", + "sha256:0ea1d73b7c9dcbc5080bb8aaffb776f1c68e807767069b9ccdd06f27a161914a", + "sha256:0f91b5b948686659a8e28b728ff5e74b1be6bf40cb04704453617e5f1e945ef3", + "sha256:15e7d1f7a6ee16572e21e3576d2012b2778cbacf75eb4b7400be37455f5ca8bf", + "sha256:17776ecd3a1fdd2b2cd5373e5ef8b307162f581c693575ec62e7c5399d80794c", + "sha256:194d0bcb1374ac3e1e023961610dc8f2c78a0f5f634d0c737691e215569e640d", + "sha256:1c0e316c9add0db48a5b703833881351444398b04111188069a26a61cfb4df78", + "sha256:205e40ccde0f37496904572035deea747390a8b7dc65146d30b96e2dd1359a83", + "sha256:273f158fabc5ea33cbc936da0ab3d4ba80ede5351babc4f577d768e057651531", + "sha256:2876246527c91e101184f63ccd1d716ec9c46519cc5f3d5375a3351c46467c46", + "sha256:2c98384b254b37ce50eddd55db8d381a5c53b4c10ee66e1e7fe749824f894021", + "sha256:2e5a26f16503be6c826abca904e45f1a44ff275fdb7e9d1b75c10671c26f8b94", + "sha256:334701327f37c47fa628fc8b8d28c7d7730ce7daaf4bda1efb741679c2b087fc", + "sha256:3748fac0d0f6a304e674955ab1365d515993b3a0a865e16a11ec9d86fb307f63", + "sha256:3c02411a3b62668200910090a0dff17c0b25aaa36145082a5a6adf08fa281e54", + "sha256:3dd4952748521205697bc2802e4afac5ed4b02909bb799ba1fe239f77fd4e117", + "sha256:3f24df7124c323fceb53ff6168da70dbfbae1442b4f3da439cd441681f54fe25", + "sha256:469e2407e0fe9880ac690a3666f03eb4c3c444411a5a5fddfdabc5d184a79f05", + "sha256:4de4bc9b6d35c5af65b454d3e9bc98c50eb3960d5a3762c9438df57427134b8e", + "sha256:5208ebd5152e040640518a77827bdfcc73773a15a33d6644015b763b9c9febc1", + "sha256:52de7fc6c21b419078008f697fd4103dbc763288b1406b4562554bd47514c004", + "sha256:5bb3489b4558e49ad2c5118137cfeaf59434f9737fa9c5deefc72d22c23822e2", + "sha256:5dba5f530fec3f0988d83b78cc591b58c0b6eb8431a85edd1569a0539a8a5a0e", + "sha256:5dd9ca406499444f4c8299f803d4a14edf7890ecc595c8b1c7115c2342cadc5f", + "sha256:5f931a1c21dfa7a9c573ec1f50a31135ccce84e32507c54e1ea404894c5eb96f", + "sha256:63b82bb63de7c821428d513607e84c6d97d58afd1fe2eb645030bdc185440120", + "sha256:66c0061c91b3b9cf542131148ef7ecbecb2690d48d1612ec386de9d36766058f", + "sha256:6f0c02cbb9691b7c91d5009108f975f8ffeab5dff8f26d62e21c493060eff2a1", + "sha256:71aace0c42d53abe6fc7f726c5d3b60d90f3c5c055a447950ad6ea9cec2e37d9", + "sha256:7d97a4306898b05404a0dcdc32d9709b7d8832c0c542b861d9a826301719794e", + "sha256:7df1e1c05304f26faa49fa752a8c690126cf98b40b91d54e6e9cc3b7d6ffe8b7", + "sha256:8270252effc60b9642b423189a2fe90eb6b59e87cbee54549db3f5562ff8d1b8", + "sha256:867a5ad16892bf20e6c4ea2aab1971f45645ff3102ad29bd84c86027fa99997b", + "sha256:877473e675fdcc113c138813a5dd440da0769a2d81f4d86614e5d62b69497155", + "sha256:8892f89999ffd992208754851e5a052f6b5db70a1e3f7d54b17c5211e37a98c7", + "sha256:9a9845c4c6bb56e508651f005c4aeb0404e518c6f000d5a1123ab077ab769f5c", + "sha256:a1e6e96217a0f72e2b8629e271e1b280c6fa3fe6e59fa8f6701bec14e3354325", + "sha256:a8156e6a7f5e2a0ff0c5b21d6bcb45145efece1909efcbbbf48c56f8da68221d", + "sha256:a9506a7e80bcf6eacfff7f804c0ad5350c8c95b9010e4356a4b36f5322f09abb", + "sha256:af310ec8335016b5e52cae60cda4a4f2a60a788cbb949a4fbea13d441aa5a09e", + "sha256:b0297b1e05fd128d26cc2460c810d42e205d16d76799526dfa8c8ccd50e74959", + "sha256:bf68f4b2b6683e52bec69273562df15af352e5ed25d1b6641e7efddc5951d1a7", + "sha256:d0c1bc2fa9a7285719e5678584f6b92572a5b639d0e471bb8d4b650a1a910920", + "sha256:d4d9d6c1a455d4babd320203b918ccc7fcbefe308615c521062bc2ba1aa4d26e", + "sha256:db1fa631737dab9fa0b37f3979d8d2631e348c3b4e8325d6873c2541d0ae5a48", + "sha256:dd93ea5c0c7f3e25335ab7d22a507b1dc43976e1345508f845efc573d3d779d8", + "sha256:f44e517131a98f7a76696a7b21b164bcb85291cee106a23beccce454e1f433a4", + "sha256:f7ee479e96f7ee350db1cf24afa5685a5899e2b34992fb99e1f7c1b0b758d263" ], - "markers": "python_version >= '3.7'", - "version": "==6.0" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==5.4.0" } }, "develop": { @@ -1731,19 +1499,19 @@ }, "asgiref": { "hashes": [ - "sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac", - "sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506" + "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4", + "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424" ], "markers": "python_version >= '3.7'", - "version": "==3.6.0" + "version": "==3.5.2" }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "black": { "hashes": [ @@ -1753,6 +1521,22 @@ "index": "pypi", "version": "==19.10b0" }, + "certifi": { + "hashes": [ + "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14", + "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.9.24" + }, + "charset-normalizer": { + "hashes": [ + "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", + "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" + ], + "markers": "python_full_version >= '3.6.0'", + "version": "==2.1.1" + }, "click": { "hashes": [ "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1", @@ -1761,21 +1545,86 @@ "index": "pypi", "version": "==8.0.4" }, + "codecov": { + "hashes": [ + "sha256:585dc217dc3d8185198ceb402f85d5cb5dbfa0c5f350a5abcdf9e347776a5b47", + "sha256:782a8e5352f22593cbc5427a35320b99490eb24d9dcfa2155fd99d2b75cfb635", + "sha256:a0da46bb5025426da895af90938def8ee12d37fcbcbbbc15b6dc64cf7ebc51c1" + ], + "index": "pypi", + "version": "==2.1.12" + }, + "coverage": { + "hashes": [ + "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79", + "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a", + "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f", + "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a", + "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa", + "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398", + "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba", + "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d", + "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf", + "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b", + "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518", + "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d", + "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795", + "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2", + "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e", + "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32", + "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745", + "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b", + "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e", + "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d", + "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f", + "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660", + "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62", + "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6", + "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04", + "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c", + "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5", + "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef", + "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc", + "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae", + "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578", + "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466", + "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4", + "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91", + "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0", + "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4", + "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b", + "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe", + "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b", + "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75", + "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b", + "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c", + "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72", + "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b", + "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f", + "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e", + "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53", + "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3", + "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84", + "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987" + ], + "markers": "python_version >= '3.7'", + "version": "==6.5.0" + }, "django": { "hashes": [ - "sha256:08208dfe892eb64fff073ca743b3b952311104f939e7f6dae954fe72dcc533ba", - "sha256:4d492d9024c7b3dfababf49f94511ab6a58e2c9c3c7207786f1ba4eb77750706" + "sha256:115baf5049d5cf4163e43492cdc7139c306ed6d451e7d3571fe9612903903713", + "sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b" ], "index": "pypi", - "version": "==3.2.18" + "version": "==3.2.15" }, "django-debug-toolbar": { "hashes": [ - "sha256:89619f6e0ea1057dca47bfc429ed99b237ef70074dabc065a7faa5f00e1459cf", - "sha256:bad339d68520652ddc1580c76f136fcbc3e020fd5ed96510a89a02ec81bb3fb1" + "sha256:1e3acad24e3d351ba45c6fa2072e4164820307332a776b16c9f06d1f89503465", + "sha256:80de23066b624d3970fd296cf02d61988e5d56c31aa0dc4a428970b46e2883a8" ], "index": "pypi", - "version": "==4.0.0" + "version": "==3.7.0" }, "django-extensions": { "hashes": [ @@ -1787,119 +1636,118 @@ }, "flake8": { "hashes": [ - "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7", - "sha256:93aa565ae2f0316b95bb57a354f2b2d55ee8508e1fe1cb13b77b9c195b4a2537", - "sha256:b27fd7faa8d90aaae763664a489012292990388e5d3604f383b290caefbbc922", - "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181" + "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db", + "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248" ], "index": "pypi", - "version": "==5.0.3" + "version": "==5.0.4" }, "flake8-isort": { "hashes": [ - "sha256:537f453a660d7e903f602ecfa36136b140de279df58d02eb1b6a0c84e83c528c", - "sha256:aa0cac02a62c7739e370ce6b9c31743edac904bae4b157274511fc8a19c75bbc" + "sha256:26571500cd54976bbc0cf1006ffbcd1a68dd102f816b7a1051b219616ba9fee0", + "sha256:5b87630fb3719bf4c1833fd11e0d9534f43efdeba524863e15d8f14a7ef6adbf" ], "index": "pypi", - "version": "==6.0.0" + "version": "==4.2.0" }, "flake8-quotes": { "hashes": [ - "sha256:6e26892b632dacba517bf27219c459a8396dcfac0f5e8204904c5a4ba9b480e1" + "sha256:633adca6fb8a08131536af0d750b44d6985b9aba46f498871e21588c3e6f525a" ], "index": "pypi", - "version": "==3.3.2" + "version": "==3.3.1" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" }, "isort": { "hashes": [ - "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", - "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" + "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", + "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" ], "index": "pypi", - "version": "==5.12.0" + "version": "==5.10.1" }, "lxml": { "hashes": [ - "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7", - "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726", - "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03", - "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140", - "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a", - "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05", - "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03", - "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419", - "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4", - "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e", - "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67", - "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50", - "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894", - "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf", - "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947", - "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1", - "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd", - "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3", - "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92", - "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3", - "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457", - "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74", - "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf", - "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1", - "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4", - "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975", - "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5", - "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe", - "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7", - "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1", - "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2", - "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409", - "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f", - "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f", - "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5", - "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24", - "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e", - "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4", - "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a", - "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c", - "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de", - "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f", - "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b", - "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5", - "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7", - "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a", - "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c", - "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9", - "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e", - "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab", - "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941", - "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5", - "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45", - "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7", - "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892", - "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746", - "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c", - "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53", - "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe", - "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184", - "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38", - "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df", - "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9", - "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b", - "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2", - "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0", - "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda", - "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b", - "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5", - "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380", - "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33", - "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8", - "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1", - "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889", - "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9", - "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f", - "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c" + "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318", + "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c", + "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b", + "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000", + "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73", + "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d", + "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb", + "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8", + "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2", + "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345", + "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94", + "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e", + "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b", + "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc", + "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a", + "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9", + "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc", + "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387", + "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb", + "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7", + "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4", + "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97", + "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67", + "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627", + "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7", + "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd", + "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3", + "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7", + "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130", + "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b", + "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036", + "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785", + "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca", + "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91", + "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc", + "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536", + "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391", + "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3", + "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d", + "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21", + "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3", + "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d", + "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29", + "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715", + "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed", + "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25", + "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c", + "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785", + "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837", + "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4", + "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b", + "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2", + "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067", + "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448", + "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d", + "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2", + "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc", + "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c", + "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5", + "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84", + "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8", + "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf", + "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7", + "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e", + "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb", + "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b", + "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3", + "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad", + "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8", + "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.9.2" + "version": "==4.9.1" }, "mccabe": { "hashes": [ @@ -1911,11 +1759,11 @@ }, "pathspec": { "hashes": [ - "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687", - "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293" + "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93", + "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d" ], "markers": "python_version >= '3.7'", - "version": "==0.11.1" + "version": "==0.10.1" }, "pycodestyle": { "hashes": [ @@ -1933,79 +1781,122 @@ "markers": "python_version >= '3.6'", "version": "==2.5.0" }, + "pytz": { + "hashes": [ + "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197", + "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5" + ], + "version": "==2022.2.1" + }, "regex": { "hashes": [ - "sha256:086afe222d58b88b62847bdbd92079b4699350b4acab892f88a935db5707c790", - "sha256:0b8eb1e3bca6b48dc721818a60ae83b8264d4089a4a41d62be6d05316ec38e15", - "sha256:11d00c31aeab9a6e0503bc77e73ed9f4527b3984279d997eb145d7c7be6268fd", - "sha256:11d1f2b7a0696dc0310de0efb51b1f4d813ad4401fe368e83c0c62f344429f98", - "sha256:1b1fc2632c01f42e06173d8dd9bb2e74ab9b0afa1d698058c867288d2c7a31f3", - "sha256:20abe0bdf03630fe92ccafc45a599bca8b3501f48d1de4f7d121153350a2f77d", - "sha256:22720024b90a6ba673a725dcc62e10fb1111b889305d7c6b887ac7466b74bedb", - "sha256:2472428efc4127374f494e570e36b30bb5e6b37d9a754f7667f7073e43b0abdd", - "sha256:25f0532fd0c53e96bad84664171969de9673b4131f2297f1db850d3918d58858", - "sha256:2848bf76673c83314068241c8d5b7fa9ad9bed866c979875a0e84039349e8fa7", - "sha256:37ae17d3be44c0b3f782c28ae9edd8b47c1f1776d4cabe87edc0b98e1f12b021", - "sha256:3cd9f5dd7b821f141d3a6ca0d5d9359b9221e4f051ca3139320adea9f1679691", - "sha256:4479f9e2abc03362df4045b1332d4a2b7885b245a30d4f4b051c4083b97d95d8", - "sha256:4c49552dc938e3588f63f8a78c86f3c9c75301e813bca0bef13bdb4b87ccf364", - "sha256:539dd010dc35af935b32f248099e38447bbffc10b59c2b542bceead2bed5c325", - "sha256:54c3fa855a3f7438149de3211738dd9b5f0c733f48b54ae05aa7fce83d48d858", - "sha256:55ae114da21b7a790b90255ea52d2aa3a0d121a646deb2d3c6a3194e722fc762", - "sha256:5ccfafd98473e007cebf7da10c1411035b7844f0f204015efd050601906dbb53", - "sha256:5fc33b27b1d800fc5b78d7f7d0f287e35079ecabe68e83d46930cf45690e1c8c", - "sha256:6560776ec19c83f3645bbc5db64a7a5816c9d8fb7ed7201c5bcd269323d88072", - "sha256:6572ff287176c0fb96568adb292674b421fa762153ed074d94b1d939ed92c253", - "sha256:6b190a339090e6af25f4a5fd9e77591f6d911cc7b96ecbb2114890b061be0ac1", - "sha256:7304863f3a652dab5e68e6fb1725d05ebab36ec0390676d1736e0571ebb713ef", - "sha256:75f288c60232a5339e0ff2fa05779a5e9c74e9fc085c81e931d4a264501e745b", - "sha256:7868b8f218bf69a2a15402fde08b08712213a1f4b85a156d90473a6fb6b12b09", - "sha256:787954f541ab95d8195d97b0b8cf1dc304424adb1e07365967e656b92b38a699", - "sha256:78ac8dd8e18800bb1f97aad0d73f68916592dddf233b99d2b5cabc562088503a", - "sha256:79e29fd62fa2f597a6754b247356bda14b866131a22444d67f907d6d341e10f3", - "sha256:845a5e2d84389c4ddada1a9b95c055320070f18bb76512608374aca00d22eca8", - "sha256:86b036f401895e854de9fefe061518e78d506d8a919cc250dc3416bca03f6f9a", - "sha256:87d9951f5a538dd1d016bdc0dcae59241d15fa94860964833a54d18197fcd134", - "sha256:8a9c63cde0eaa345795c0fdeb19dc62d22e378c50b0bc67bf4667cd5b482d98b", - "sha256:93f3f1aa608380fe294aa4cb82e2afda07a7598e828d0341e124b8fd9327c715", - "sha256:9bf4a5626f2a0ea006bf81e8963f498a57a47d58907eaa58f4b3e13be68759d8", - "sha256:9d764514d19b4edcc75fd8cb1423448ef393e8b6cbd94f38cab983ab1b75855d", - "sha256:a610e0adfcb0fc84ea25f6ea685e39e74cbcd9245a72a9a7aab85ff755a5ed27", - "sha256:a81c9ec59ca2303acd1ccd7b9ac409f1e478e40e96f8f79b943be476c5fdb8bb", - "sha256:b7006105b10b59971d3b248ad75acc3651c7e4cf54d81694df5a5130a3c3f7ea", - "sha256:c07ce8e9eee878a48ebeb32ee661b49504b85e164b05bebf25420705709fdd31", - "sha256:c125a02d22c555e68f7433bac8449992fa1cead525399f14e47c2d98f2f0e467", - "sha256:c37df2a060cb476d94c047b18572ee2b37c31f831df126c0da3cd9227b39253d", - "sha256:c869260aa62cee21c5eb171a466c0572b5e809213612ef8d495268cd2e34f20d", - "sha256:c88e8c226473b5549fe9616980ea7ca09289246cfbdf469241edf4741a620004", - "sha256:cd1671e9d5ac05ce6aa86874dd8dfa048824d1dbe73060851b310c6c1a201a96", - "sha256:cde09c4fdd070772aa2596d97e942eb775a478b32459e042e1be71b739d08b77", - "sha256:cf86b4328c204c3f315074a61bc1c06f8a75a8e102359f18ce99fbcbbf1951f0", - "sha256:d5bbe0e1511b844794a3be43d6c145001626ba9a6c1db8f84bdc724e91131d9d", - "sha256:d895b4c863059a4934d3e874b90998df774644a41b349ebb330f85f11b4ef2c0", - "sha256:db034255e72d2995cf581b14bb3fc9c00bdbe6822b49fcd4eef79e1d5f232618", - "sha256:dbb3f87e15d3dd76996d604af8678316ad2d7d20faa394e92d9394dfd621fd0c", - "sha256:dc80df325b43ffea5cdea2e3eaa97a44f3dd298262b1c7fe9dbb2a9522b956a7", - "sha256:dd7200b4c27b68cf9c9646da01647141c6db09f48cc5b51bc588deaf8e98a797", - "sha256:df45fac182ebc3c494460c644e853515cc24f5ad9da05f8ffb91da891bfee879", - "sha256:e152461e9a0aedec7d37fc66ec0fa635eca984777d3d3c3e36f53bf3d3ceb16e", - "sha256:e2396e0678167f2d0c197da942b0b3fb48fee2f0b5915a0feb84d11b6686afe6", - "sha256:e76b6fc0d8e9efa39100369a9b3379ce35e20f6c75365653cf58d282ad290f6f", - "sha256:ea3c0cb56eadbf4ab2277e7a095676370b3e46dbfc74d5c383bd87b0d6317910", - "sha256:ef3f528fe1cc3d139508fe1b22523745aa77b9d6cb5b0bf277f48788ee0b993f", - "sha256:fdf7ad455f1916b8ea5cdbc482d379f6daf93f3867b4232d14699867a5a13af7", - "sha256:fffe57312a358be6ec6baeb43d253c36e5790e436b7bf5b7a38df360363e88e9" - ], - "markers": "python_full_version >= '3.8.0'", - "version": "==2023.3.23" + "sha256:003a2e1449d425afc817b5f0b3d4c4aa9072dd5f3dfbf6c7631b8dc7b13233de", + "sha256:0385d66e73cdd4462f3cc42c76a6576ddcc12472c30e02a2ae82061bff132c32", + "sha256:0394265391a86e2bbaa7606e59ac71bd9f1edf8665a59e42771a9c9adbf6fd4f", + "sha256:03ff695518482b946a6d3d4ce9cbbd99a21320e20d94913080aa3841f880abcd", + "sha256:079c182f99c89524069b9cd96f5410d6af437e9dca576a7d59599a574972707e", + "sha256:091efcfdd4178a7e19a23776dc2b1fafb4f57f4d94daf340f98335817056f874", + "sha256:0b664a4d33ffc6be10996606dfc25fd3248c24cc589c0b139feb4c158053565e", + "sha256:14216ea15efc13f28d0ef1c463d86d93ca7158a79cd4aec0f9273f6d4c6bb047", + "sha256:14a7ab070fa3aec288076eed6ed828587b805ef83d37c9bfccc1a4a7cfbd8111", + "sha256:14c71437ffb89479c89cc7022a5ea2075a842b728f37205e47c824cc17b30a42", + "sha256:18e503b1e515a10282b3f14f1b3d856194ecece4250e850fad230842ed31227f", + "sha256:19a4da6f513045f5ba00e491215bd00122e5bd131847586522463e5a6b2bd65f", + "sha256:1a901ce5cd42658ab8f8eade51b71a6d26ad4b68c7cfc86b87efc577dfa95602", + "sha256:26df88c9636a0c3f3bd9189dd435850a0c49d0b7d6e932500db3f99a6dd604d1", + "sha256:2dda4b096a6f630d6531728a45bd12c67ec3badf44342046dc77d4897277d4f2", + "sha256:322bd5572bed36a5b39952d88e072738926759422498a96df138d93384934ff8", + "sha256:360ffbc9357794ae41336b681dff1c0463193199dfb91fcad3ec385ea4972f46", + "sha256:37e5a26e76c46f54b3baf56a6fdd56df9db89758694516413757b7d127d4c57b", + "sha256:3d64e1a7e6d98a4cdc8b29cb8d8ed38f73f49e55fbaa737bdb5933db99b9de22", + "sha256:3f3b4594d564ed0b2f54463a9f328cf6a5b2a32610a90cdff778d6e3e561d08b", + "sha256:4146cb7ae6029fc83b5c905ec6d806b7e5568dc14297c423e66b86294bad6c39", + "sha256:4318f69b79f9f7d84a7420e97d4bfe872dc767c72f891d4fea5fa721c74685f7", + "sha256:4cdbfa6d2befeaee0c899f19222e9b20fc5abbafe5e9c43a46ef819aeb7b75e5", + "sha256:50e764ffbd08b06aa8c4e86b8b568b6722c75d301b33b259099f237c46b2134e", + "sha256:518272f25da93e02af4f1e94985f5042cec21557ef3591027d0716f2adda5d0a", + "sha256:592b9e2e1862168e71d9e612bfdc22c451261967dbd46681f14e76dfba7105fd", + "sha256:59a786a55d00439d8fae4caaf71581f2aaef7297d04ee60345c3594efef5648a", + "sha256:59bac44b5a07b08a261537f652c26993af9b1bbe2a29624473968dd42fc29d56", + "sha256:5d0dd8b06896423211ce18fba0c75dacc49182a1d6514c004b535be7163dca0f", + "sha256:67a4c625361db04ae40ef7c49d3cbe2c1f5ff10b5a4491327ab20f19f2fb5d40", + "sha256:6adfe300848d61a470ec7547adc97b0ccf86de86a99e6830f1d8c8d19ecaf6b3", + "sha256:6b32b45433df1fad7fed738fe15200b6516da888e0bd1fdd6aa5e50cc16b76bc", + "sha256:6c57d50d4d5eb0c862569ca3c840eba2a73412f31d9ecc46ef0d6b2e621a592b", + "sha256:6d43bd402b27e0e7eae85c612725ba1ce7798f20f6fab4e8bc3de4f263294f03", + "sha256:6e521d9db006c5e4a0f8acfef738399f72b704913d4e083516774eb51645ad7c", + "sha256:6fe1dd1021e0f8f3f454ce2811f1b0b148f2d25bb38c712fec00316551e93650", + "sha256:73b985c9fc09a7896846e26d7b6f4d1fd5a20437055f4ef985d44729f9f928d0", + "sha256:7681c49da1a2d4b905b4f53d86c9ba4506e79fba50c4a664d9516056e0f7dfcc", + "sha256:77c2879d3ba51e5ca6c2b47f2dcf3d04a976a623a8fc8236010a16c9e0b0a3c7", + "sha256:7b0c5cc3d1744a67c3b433dce91e5ef7c527d612354c1f1e8576d9e86bc5c5e2", + "sha256:7fcf7f94ccad19186820ac67e2ec7e09e0ac2dac39689f11cf71eac580503296", + "sha256:83cc32a1a2fa5bac00f4abc0e6ce142e3c05d3a6d57e23bd0f187c59b4e1e43b", + "sha256:8418ee2cb857b83881b8f981e4c636bc50a0587b12d98cb9b947408a3c484fe7", + "sha256:86df2049b18745f3cd4b0f4c4ef672bfac4b80ca488e6ecfd2bbfe68d2423a2c", + "sha256:880dbeb6bdde7d926b4d8e41410b16ffcd4cb3b4c6d926280fea46e2615c7a01", + "sha256:8aba0d01e3dfd335f2cb107079b07fdddb4cd7fb2d8c8a1986f9cb8ce9246c24", + "sha256:8dcbcc9e72a791f622a32d17ff5011326a18996647509cac0609a7fc43adc229", + "sha256:944567bb08f52268d8600ee5bdf1798b2b62ea002cc692a39cec113244cbdd0d", + "sha256:995e70bb8c91d1b99ed2aaf8ec44863e06ad1dfbb45d7df95f76ef583ec323a9", + "sha256:99945ddb4f379bb9831c05e9f80f02f079ba361a0fb1fba1fc3b267639b6bb2e", + "sha256:9a165a05979e212b2c2d56a9f40b69c811c98a788964e669eb322de0a3e420b4", + "sha256:9bc8edc5f8ef0ebb46f3fa0d02bd825bbe9cc63d59e428ffb6981ff9672f6de1", + "sha256:a1aec4ae549fd7b3f52ceaf67e133010e2fba1538bf4d5fc5cd162a5e058d5df", + "sha256:a1c4d17879dd4c4432c08a1ca1ab379f12ab54af569e945b6fc1c4cf6a74ca45", + "sha256:a2b39ee3b280e15824298b97cec3f7cbbe6539d8282cc8a6047a455b9a72c598", + "sha256:a2effeaf50a6838f3dd4d3c5d265f06eabc748f476e8441892645ae3a697e273", + "sha256:a59d0377e58d96a6f11636e97992f5b51b7e1e89eb66332d1c01b35adbabfe8a", + "sha256:a926339356fe29595f8e37af71db37cd87ff764e15da8ad5129bbaff35bcc5a6", + "sha256:a9eb9558e1d0f78e07082d8a70d5c4d631c8dd75575fae92105df9e19c736730", + "sha256:ab07934725e6f25c6f87465976cc69aef1141e86987af49d8c839c3ffd367c72", + "sha256:ad75173349ad79f9d21e0d0896b27dcb37bfd233b09047bc0b4d226699cf5c87", + "sha256:b7b701dbc124558fd2b1b08005eeca6c9160e209108fbcbd00091fcfac641ac7", + "sha256:b7bee775ff05c9d519195bd9e8aaaccfe3971db60f89f89751ee0f234e8aeac5", + "sha256:b86548b8234b2be3985dbc0b385e35f5038f0f3e6251464b827b83ebf4ed90e5", + "sha256:b9d68eb704b24bc4d441b24e4a12653acd07d2c39940548761e0985a08bc1fff", + "sha256:c0b7cb9598795b01f9a3dd3f770ab540889259def28a3bf9b2fa24d52edecba3", + "sha256:cab548d6d972e1de584161487b2ac1aa82edd8430d1bde69587ba61698ad1cfb", + "sha256:ce331b076b2b013e7d7f07157f957974ef0b0881a808e8a4a4b3b5105aee5d04", + "sha256:cfa4c956ff0a977c4823cb3b930b0a4e82543b060733628fec7ab3eb9b1abe37", + "sha256:d23ac6b4bf9e32fcde5fcdb2e1fd5e7370d6693fcac51ee1d340f0e886f50d1f", + "sha256:d2885ec6eea629c648ecc9bde0837ec6b92208b7f36381689937fe5d64a517e8", + "sha256:d2a1371dc73e921f3c2e087c05359050f3525a9a34b476ebc8130e71bec55e97", + "sha256:d3102ab9bf16bf541ca228012d45d88d2a567c9682a805ae2c145a79d3141fdd", + "sha256:d5b003d248e6f292475cd24b04e5f72c48412231961a675edcb653c70730e79e", + "sha256:d5edd3eb877c9fc2e385173d4a4e1d792bf692d79e25c1ca391802d36ecfaa01", + "sha256:d7430f041755801b712ec804aaf3b094b9b5facbaa93a6339812a8e00d7bd53a", + "sha256:d837ccf3bd2474feabee96cd71144e991472e400ed26582edc8ca88ce259899c", + "sha256:dab81cc4d58026861445230cfba27f9825e9223557926e7ec22156a1a140d55c", + "sha256:db45016364eec9ddbb5af93c8740c5c92eb7f5fc8848d1ae04205a40a1a2efc6", + "sha256:df8fe00b60e4717662c7f80c810ba66dcc77309183c76b7754c0dff6f1d42054", + "sha256:e6e6e61e9a38b6cc60ca3e19caabc90261f070f23352e66307b3d21a24a34aaf", + "sha256:ee7045623a5ace70f3765e452528b4c1f2ce669ed31959c63f54de64fe2f6ff7", + "sha256:f06cc1190f3db3192ab8949e28f2c627e1809487e2cfc435b6524c1ce6a2f391", + "sha256:f07373b6e56a6f3a0df3d75b651a278ca7bd357a796078a26a958ea1ce0588fd", + "sha256:f6e0321921d2fdc082ef90c1fd0870f129c2e691bfdc4937dcb5cd308aba95c4", + "sha256:f6e167d1ccd41d27b7b6655bb7a2dcb1b1eb1e0d2d662043470bd3b4315d8b2b", + "sha256:fcbd1edff1473d90dc5cf4b52d355cf1f47b74eb7c85ba6e45f45d0116b8edbd", + "sha256:fe428822b7a8c486bcd90b334e9ab541ce6cc0d6106993d59f201853e5e14121" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.9.13" + }, + "requests": { + "hashes": [ + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" + ], + "markers": "python_version >= '3.7' and python_version < '4'", + "version": "==2.28.1" }, "sqlparse": { "hashes": [ - "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", - "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" + "sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34", + "sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268" ], - "markers": "python_full_version >= '3.5.0'", - "version": "==0.4.4" + "markers": "python_version >= '3.5'", + "version": "==0.4.3" }, "toml": { "hashes": [ @@ -2045,14 +1936,6 @@ "markers": "python_version >= '3.6'", "version": "==1.5.4" }, - "typing-extensions": { - "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" - ], - "markers": "python_version >= '3.7'", - "version": "==4.5.0" - }, "unittest-xml-reporting": { "hashes": [ "sha256:edd8d3170b40c3a81b8cf910f46c6a304ae2847ec01036d02e9c0f9b85762d28", @@ -2060,6 +1943,14 @@ ], "index": "pypi", "version": "==3.2.0" + }, + "urllib3": { + "hashes": [ + "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e", + "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997" + ], + "markers": "python_version >= '3.6'", + "version": "==1.26.12" } } } diff --git a/backend/clubs/admin.py b/backend/clubs/admin.py index 24557da10..9dcd1c7c5 100644 --- a/backend/clubs/admin.py +++ b/backend/clubs/admin.py @@ -14,8 +14,6 @@ AdminNote, Advisor, ApplicationCommittee, - ApplicationCycle, - ApplicationExtension, ApplicationMultipleChoice, ApplicationQuestion, ApplicationQuestionResponse, @@ -408,18 +406,12 @@ class ZoomMeetingVisitAdmin(admin.ModelAdmin): list_filter = (("leave_time", admin.EmptyFieldListFilter),) -class ApplicationSubmissionAdmin(admin.ModelAdmin): - search_fields = ("user__username",) - list_display = ("user", "id", "created_at", "status") - - admin.site.register(Asset) admin.site.register(ApplicationCommittee) -admin.site.register(ApplicationExtension) admin.site.register(ApplicationMultipleChoice) admin.site.register(ApplicationQuestion) admin.site.register(ApplicationQuestionResponse) -admin.site.register(ApplicationSubmission, ApplicationSubmissionAdmin) +admin.site.register(ApplicationSubmission) admin.site.register(Advisor, AdvisorAdmin) admin.site.register(Club, ClubAdmin) admin.site.register(ClubFair, ClubFairAdmin) @@ -453,6 +445,5 @@ class ApplicationSubmissionAdmin(admin.ModelAdmin): admin.site.register(Year, YearAdmin) admin.site.register(ZoomMeetingVisit, ZoomMeetingVisitAdmin) admin.site.register(AdminNote) -admin.site.register(ApplicationCycle) admin.site.register(Ticket) admin.site.register(Cart) diff --git a/backend/clubs/management/commands/populate.py b/backend/clubs/management/commands/populate.py index 57c8f3236..a499bacef 100644 --- a/backend/clubs/management/commands/populate.py +++ b/backend/clubs/management/commands/populate.py @@ -226,7 +226,7 @@ members and to answer questions.

- If you would like to particpate in the SAC fair, check + If you would like to particpate in the Fall 2020 SAC fair, check the box below. If you check the box below, your club information will be shared with the Student Activites Council and more details will be sent to you at a later date. @@ -396,12 +396,6 @@ def get_image(url): tag_undergrad, _ = Tag.objects.get_or_create(name="Undergraduate") tag_generic, _ = Tag.objects.get_or_create(name="Generic") - wharton_badge, _ = Badge.objects.get_or_create( - label="Wharton Council", - purpose="Dummy badge to mock Wharton-affiliated clubs", - visible=True, - ) - for i in range(1, 50): club, created = Club.objects.get_or_create( code="z-club-{}".format(i), @@ -414,10 +408,6 @@ def get_image(url): }, ) - if 10 <= i <= 15: - # Make some clubs Wharton-affiliated - club.badges.add(wharton_badge) - if created: club.available_virtually = i % 2 == 0 club.appointment_needed = i % 3 == 0 diff --git a/backend/clubs/management/commands/update_club_counts.py b/backend/clubs/management/commands/update_club_counts.py deleted file mode 100644 index 01ff17676..000000000 --- a/backend/clubs/management/commands/update_club_counts.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.core.management.base import BaseCommand -from django.db.models import Count, Q - -from clubs.models import Club - - -class Command(BaseCommand): - help = "Update stored favorite and membership counts." - - def handle(self, *args, **kwargs): - try: - queryset = Club.objects.all().annotate( - temp_favorite_count=Count("favorite", distinct=True), - temp_membership_count=Count( - "membership", distinct=True, filter=Q(active=True) - ), - ) - - for club in queryset: - club.favorite_count = club.temp_favorite_count - club.membership_count = club.temp_membership_count - Club.objects.bulk_update(queryset, ["favorite_count", "membership_count"]) - - self.stdout.write( - self.style.SUCCESS( - "Successfully updated all club favorite and membership counts!" - ) - ) - except Exception as e: - self.stdout.write( - self.style.ERROR( - "An error was encountered while updating" - + "club favorite and membership counts!" - ) - ) - self.stdout.write(e) diff --git a/backend/clubs/management/commands/wharton_council_application.py b/backend/clubs/management/commands/wharton_council_application.py new file mode 100644 index 000000000..3fe8c75af --- /dev/null +++ b/backend/clubs/management/commands/wharton_council_application.py @@ -0,0 +1,135 @@ +from datetime import datetime + +from django.core.management.base import BaseCommand + +from clubs.models import ( + ApplicationMultipleChoice, + ApplicationQuestion, + Badge, + Club, + ClubApplication, +) + + +class Command(BaseCommand): + help = "Helper to automatically create the Wharton council club applications." + web_execute = True + + def add_arguments(self, parser): + parser.add_argument( + "application_start_time", + type=str, + help="Date and time at which the centralized application opens.", + ) + parser.add_argument( + "application_end_time", + type=str, + help="Date and time at which the centralized application closes.", + ) + parser.add_argument( + "result_release_time", + type=str, + help="Date and time at which the centralized application results " + "are released.", + ) + parser.add_argument( + "--dry-run", + dest="dry_run", + action="store_true", + help="Do not actually create applications.", + ) + parser.add_argument( + "--clubs", + dest="clubs", + type=str, + help="The comma separated list of club codes for which to create the " + "centralized applications.", + ) + parser.set_defaults( + application_start_time="2021-09-04 00:00:00", + application_end_time="2021-09-04 00:00:00", + result_release_time="2021-09-04 00:00:00", + dry_run=False, + clubs="", + ) + + def handle(self, *args, **kwargs): + dry_run = kwargs["dry_run"] + club_names = list(map(lambda x: x.strip(), kwargs["clubs"].split(","))) + clubs = [] + + if club_names == [] or all(not name for name in club_names): + wc_badge = Badge.objects.filter( + label="Wharton Council", purpose="org", + ).first() + for club in Club.objects.all(): + if wc_badge in club.badges.all(): + clubs.append(club) + else: + for code in club_names: + target_club = Club.objects.filter(code=code).first() + if target_club is not None: + clubs.append(target_club) + + application_start_time = datetime.strptime( + kwargs["application_start_time"], "%Y-%m-%d %H:%M:%S" + ) + application_end_time = datetime.strptime( + kwargs["application_end_time"], "%Y-%m-%d %H:%M:%S" + ) + result_release_time = datetime.strptime( + kwargs["result_release_time"], "%Y-%m-%d %H:%M:%S" + ) + + prompt_one = ( + "Tell us about a time you took " "initiative or demonstrated leadership" + ) + prompt_two = "Tell us about a time you faced a challenge and how you solved it" + prompt_three = "Tell us about a time you collaborated well in a team" + + if len(clubs) == 0: + self.stdout.write("No valid club codes provided, returning...") + + for club in clubs: + name = f"{club.name} Application" + if dry_run: + self.stdout.write(f"Would have created application for {club.name}") + else: + self.stdout.write(f"Creating application for {club.name}") + application = ClubApplication.objects.create( + name=name, + club=club, + application_start_time=application_start_time, + application_end_time=application_end_time, + result_release_time=result_release_time, + is_wharton_council=True, + ) + external_url = ( + f"https://pennclubs.com/club/{club.code}/" + f"application/{application.pk}" + ) + application.external_url = external_url + application.save() + prompt = ( + "Choose one of the following " "prompts for your personal statement" + ) + prompt_question = ApplicationQuestion.objects.create( + question_type=ApplicationQuestion.MULTIPLE_CHOICE, + application=application, + prompt=prompt, + ) + ApplicationMultipleChoice.objects.create( + value=prompt_one, question=prompt_question + ) + ApplicationMultipleChoice.objects.create( + value=prompt_two, question=prompt_question + ) + ApplicationMultipleChoice.objects.create( + value=prompt_three, question=prompt_question + ) + ApplicationQuestion.objects.create( + question_type=ApplicationQuestion.FREE_RESPONSE, + prompt="Answer the prompt you selected", + word_limit=150, + application=application, + ) diff --git a/backend/clubs/migrations/0088_alter_applicationsubmission_status.py b/backend/clubs/migrations/0088_alter_applicationsubmission_status.py new file mode 100644 index 000000000..5710f001a --- /dev/null +++ b/backend/clubs/migrations/0088_alter_applicationsubmission_status.py @@ -0,0 +1,45 @@ +# Generated by Django 3.2.6 on 2021-10-06 21:33 + +from django.db import migrations, models + +from clubs.models import ApplicationSubmission + + +def reassign_status(apps, schema_editor): + submissions = ApplicationSubmission.objects.all() + for submission in submissions: + if submission.status == 1: + pass + elif submission.status == 2: + submission.status = ApplicationSubmission.PENDING + elif submission.status == 3: + submission.status = ApplicationSubmission.PENDING + elif submission.status == 4: + pass + elif submission.status == 5: + submission.status = ApplicationSubmission.REJECTED_AFTER_WRITTEN + submission.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ("clubs", "0087_questionanswer_users_liked"), + ] + + operations = [ + migrations.AlterField( + model_name="applicationsubmission", + name="status", + field=models.IntegerField( + choices=[ + (1, "Pending"), + (2, "Rejected after interview(s)"), + (3, "Rejected after written application"), + (4, "Accepted"), + ], + default=1, + ), + ), + migrations.RunPython(reassign_status), + ] diff --git a/backend/clubs/migrations/0089_alter_applicationsubmission_status.py b/backend/clubs/migrations/0089_alter_applicationsubmission_status.py new file mode 100644 index 000000000..9db95bf25 --- /dev/null +++ b/backend/clubs/migrations/0089_alter_applicationsubmission_status.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.6 on 2021-10-06 22:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("clubs", "0088_alter_applicationsubmission_status"), + ] + + operations = [ + migrations.AlterField( + model_name="applicationsubmission", + name="status", + field=models.IntegerField( + choices=[ + (1, "Pending"), + (2, "Rejected after written application"), + (3, "Rejected after interview(s)"), + (4, "Accepted"), + ], + default=1, + ), + ), + ] diff --git a/backend/clubs/migrations/0089_auto_20230103_1239.py b/backend/clubs/migrations/0089_auto_20230103_1239.py deleted file mode 100644 index f027204f2..000000000 --- a/backend/clubs/migrations/0089_auto_20230103_1239.py +++ /dev/null @@ -1,60 +0,0 @@ -# Generated by Django 3.2.16 on 2023-01-03 17:39 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("clubs", "0088_adminnote"), - ] - - operations = [ - migrations.AlterModelOptions( - name="historicalclub", - options={ - "get_latest_by": ("history_date", "history_id"), - "ordering": ("-history_date", "-history_id"), - "verbose_name": "historical club", - "verbose_name_plural": "historical clubs", - }, - ), - migrations.AddField( - model_name="applicationsubmission", - name="notified", - field=models.BooleanField(default=False), - ), - migrations.AddField( - model_name="applicationsubmission", - name="reason", - field=models.TextField(blank=True), - ), - migrations.AddField( - model_name="clubapplication", - name="acceptance_email", - field=models.TextField(blank=True), - ), - migrations.AddField( - model_name="clubapplication", - name="rejection_email", - field=models.TextField(blank=True), - ), - migrations.AlterField( - model_name="applicationsubmission", - name="status", - field=models.IntegerField( - choices=[ - (1, "Pending"), - (2, "Rejected after written application"), - (3, "Rejected after interview(s)"), - (4, "Accepted"), - ], - default=1, - ), - ), - migrations.AlterField( - model_name="historicalclub", - name="history_date", - field=models.DateTimeField(db_index=True), - ), - ] diff --git a/backend/clubs/migrations/0088_adminnote.py b/backend/clubs/migrations/0090_adminnote.py similarity index 95% rename from backend/clubs/migrations/0088_adminnote.py rename to backend/clubs/migrations/0090_adminnote.py index e6ad481cc..d75043e60 100644 --- a/backend/clubs/migrations/0088_adminnote.py +++ b/backend/clubs/migrations/0090_adminnote.py @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("clubs", "0087_questionanswer_users_liked"), + ("clubs", "0089_alter_applicationsubmission_status"), ] operations = [ diff --git a/backend/clubs/migrations/0090_auto_20230106_1443.py b/backend/clubs/migrations/0090_auto_20230106_1443.py deleted file mode 100644 index d7ce13226..000000000 --- a/backend/clubs/migrations/0090_auto_20230106_1443.py +++ /dev/null @@ -1,40 +0,0 @@ -# Generated by Django 3.2.16 on 2023-01-06 19:43 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("clubs", "0089_auto_20230103_1239"), - ] - - operations = [ - migrations.CreateModel( - name="ApplicationCycle", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.CharField(max_length=255)), - ("start_date", models.DateTimeField(null=True)), - ("end_date", models.DateTimeField(null=True)), - ], - ), - migrations.AddField( - model_name="clubapplication", - name="application_cycle", - field=models.ForeignKey( - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="clubs.applicationcycle", - ), - ), - ] diff --git a/backend/clubs/migrations/0091_applicationextension.py b/backend/clubs/migrations/0091_applicationextension.py deleted file mode 100644 index 43cd96efd..000000000 --- a/backend/clubs/migrations/0091_applicationextension.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 3.2.18 on 2023-11-25 03:58 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("clubs", "0090_auto_20230106_1443"), - ] - - operations = [ - migrations.CreateModel( - name="ApplicationExtension", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("end_time", models.DateTimeField()), - ( - "application", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="extensions", - to="clubs.clubapplication", - ), - ), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ], - options={"unique_together": {("user", "application")}}, - ), - ] diff --git a/backend/clubs/migrations/0096_cart_ticket.py b/backend/clubs/migrations/0091_cart_ticket.py similarity index 98% rename from backend/clubs/migrations/0096_cart_ticket.py rename to backend/clubs/migrations/0091_cart_ticket.py index 54b1afa63..74ae8cdd9 100644 --- a/backend/clubs/migrations/0096_cart_ticket.py +++ b/backend/clubs/migrations/0091_cart_ticket.py @@ -11,7 +11,7 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("clubs", "0095_rm_field_add_count"), + ("clubs", "0090_adminnote"), ] operations = [ diff --git a/backend/clubs/migrations/0091_clubapplication_application_end_time_exception.py b/backend/clubs/migrations/0091_clubapplication_application_end_time_exception.py deleted file mode 100644 index 92377bdb5..000000000 --- a/backend/clubs/migrations/0091_clubapplication_application_end_time_exception.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.18 on 2023-11-17 22:01 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("clubs", "0090_auto_20230106_1443"), - ] - - operations = [ - migrations.AddField( - model_name="clubapplication", - name="application_end_time_exception", - field=models.BooleanField(blank=True, default=False), - ), - ] diff --git a/backend/clubs/migrations/0092_merge_20240106_1117.py b/backend/clubs/migrations/0092_merge_20240106_1117.py deleted file mode 100644 index 9656c2c26..000000000 --- a/backend/clubs/migrations/0092_merge_20240106_1117.py +++ /dev/null @@ -1,13 +0,0 @@ -# Generated by Django 3.2.18 on 2024-01-06 16:17 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("clubs", "0091_applicationextension"), - ("clubs", "0091_clubapplication_application_end_time_exception"), - ] - - operations = [] diff --git a/backend/clubs/migrations/0093_auto_20240106_1153.py b/backend/clubs/migrations/0093_auto_20240106_1153.py deleted file mode 100644 index 1e2ab1a0f..000000000 --- a/backend/clubs/migrations/0093_auto_20240106_1153.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.2.18 on 2024-01-06 16:53 - -from django.conf import settings -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("clubs", "0092_merge_20240106_1117"), - ] - - operations = [ - migrations.AlterUniqueTogether( - name="applicationquestionresponse", - unique_together={("question", "submission")}, - ), - migrations.AlterUniqueTogether( - name="applicationsubmission", - unique_together={("user", "application", "committee")}, - ), - ] diff --git a/backend/clubs/migrations/0094_applicationcycle_release_date.py b/backend/clubs/migrations/0094_applicationcycle_release_date.py deleted file mode 100644 index 62ad134f9..000000000 --- a/backend/clubs/migrations/0094_applicationcycle_release_date.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.18 on 2024-01-11 14:39 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("clubs", "0093_auto_20240106_1153"), - ] - - operations = [ - migrations.AddField( - model_name="applicationcycle", - name="release_date", - field=models.DateTimeField(null=True), - ), - ] diff --git a/backend/clubs/migrations/0095_rm_field_add_count.py b/backend/clubs/migrations/0095_rm_field_add_count.py deleted file mode 100644 index f3ada60c1..000000000 --- a/backend/clubs/migrations/0095_rm_field_add_count.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.2.18 on 2024-02-03 22:21 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("clubs", "0094_applicationcycle_release_date"), - ] - - operations = [ - migrations.RemoveField(model_name="applicationsubmission", name="archived",), - migrations.AddField( - model_name="club", - name="favorite_count", - field=models.IntegerField(default=0), - ), - migrations.AddField( - model_name="club", - name="membership_count", - field=models.IntegerField(default=0), - ), - migrations.AddField( - model_name="historicalclub", - name="favorite_count", - field=models.IntegerField(default=0), - ), - migrations.AddField( - model_name="historicalclub", - name="membership_count", - field=models.IntegerField(default=0), - ), - ] diff --git a/backend/clubs/mixins.py b/backend/clubs/mixins.py index 16fc46137..22afe3964 100644 --- a/backend/clubs/mixins.py +++ b/backend/clubs/mixins.py @@ -148,7 +148,7 @@ def get_xlsx_column_name(self, key): if hasattr(serializer_class, "get_xlsx_column_name"): val = serializer_class.get_xlsx_column_name(key) if val is None: - val = key.replace("_", " ") + val = key.replace("_", " ").title() self._column_cache[key] = val return val diff --git a/backend/clubs/models.py b/backend/clubs/models.py index cf622c0ae..4e7026497 100644 --- a/backend/clubs/models.py +++ b/backend/clubs/models.py @@ -22,9 +22,7 @@ from django.template.loader import render_to_string from django.utils import timezone from django.utils.crypto import get_random_string -from django.utils.functional import cached_property from ics import Calendar -from jinja2 import Environment, meta from model_clone.models import CloneModel from phonenumber_field.modelfields import PhoneNumberField from simple_history.models import HistoricalRecords @@ -325,13 +323,6 @@ class Club(models.Model): appointment_needed = models.BooleanField(default=False) signature_events = models.TextField(blank=True) # html - # cache club aggregation counts - favorite_count = models.IntegerField(default=0) - membership_count = models.IntegerField(default=0) - - # cache club rankings - rank = models.IntegerField(default=0) - # cache club rankings rank = models.IntegerField(default=0) @@ -347,11 +338,6 @@ def __str__(self): def create_thumbnail(self, request=None): return create_thumbnail_helper(self, request, 200) - @cached_property - def is_wharton(self): - wc_badge = Badge.objects.filter(label="Wharton Council").first() - return wc_badge in self.badges.all() - def add_ics_events(self): """ Fetch the ICS events from the club's calendar URL @@ -1540,43 +1526,22 @@ def __str__(self): return self.user.username -class ApplicationCycle(models.Model): - """ - Represents an application cycle attached to club applications - """ - - name = models.CharField(max_length=255) - start_date = models.DateTimeField(null=True) - end_date = models.DateTimeField(null=True) - release_date = models.DateTimeField(null=True) - - def __str__(self): - return self.name - - class ClubApplication(CloneModel): """ Represents custom club application. """ DEFAULT_COMMITTEE = "General Member" - VALID_TEMPLATE_TOKENS = {"name", "reason", "committee"} club = models.ForeignKey(Club, on_delete=models.CASCADE) description = models.TextField(blank=True) application_start_time = models.DateTimeField() application_end_time = models.DateTimeField() - application_end_time_exception = models.BooleanField(default=False, blank=True) name = models.TextField(blank=True) result_release_time = models.DateTimeField() - application_cycle = models.ForeignKey( - ApplicationCycle, on_delete=models.SET_NULL, null=True - ) external_url = models.URLField(blank=True) is_active = models.BooleanField(default=False, blank=True) is_wharton_council = models.BooleanField(default=False, blank=True) - acceptance_email = models.TextField(blank=True) - rejection_email = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -1594,53 +1559,12 @@ def __str__(self): self.application_end_time, ) - @cached_property + @property def season(self): - semester = "Fall" if 8 <= self.application_start_time.month <= 12 else "Spring" + semester = "Fall" if 8 <= self.application_start_time.month <= 11 else "Spring" year = str(self.application_start_time.year) return f"{semester} {year}" - @classmethod - def validate_template(cls, template): - environment = Environment() - j2_template = environment.parse(template) - tokens = meta.find_undeclared_variables(j2_template) - return all(t in cls.VALID_TEMPLATE_TOKENS for t in tokens) - - -class ApplicationExtension(models.Model): - """ - Represents an individual club application extension. - """ - - user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) - application = models.ForeignKey( - ClubApplication, related_name="extensions", on_delete=models.CASCADE - ) - end_time = models.DateTimeField() - - def send_extension_mail(self): - context = { - "name": self.user.first_name, - "application_name": self.application.name, - "end_time": self.end_time, - "club": self.application.club.name, - "url": ( - f"https://pennclubs.com/club/{self.application.club.code}" - f"/application/{self.application.pk}/" - ), - } - - send_mail_helper( - name="application_extension", - subject=f"Application Extension for {self.application.name}", - emails=[self.user.email], - context=context, - ) - - class Meta: - unique_together = (("user", "application"),) - class ApplicationCommittee(models.Model): """ @@ -1724,7 +1648,6 @@ class ApplicationSubmission(models.Model): ) status = models.IntegerField(choices=STATUS_TYPES, default=PENDING) user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, null=False) - reason = models.TextField(blank=True) application = models.ForeignKey( ClubApplication, related_name="submissions", @@ -1737,16 +1660,10 @@ class ApplicationSubmission(models.Model): on_delete=models.SET_NULL, null=True, ) - notified = models.BooleanField(default=False) + archived = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) - def __str__(self): - return f"{self.user.first_name}: {self.application.name}" - - class Meta: - unique_together = (("user", "application", "committee"),) - class ApplicationQuestionResponse(models.Model): """ @@ -1775,9 +1692,6 @@ class ApplicationQuestionResponse(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) - class Meta: - unique_together = (("question", "submission"),) - class QuestionResponse(models.Model): """ diff --git a/backend/clubs/serializers.py b/backend/clubs/serializers.py index 573a58e4f..f44761caa 100644 --- a/backend/clubs/serializers.py +++ b/backend/clubs/serializers.py @@ -1,12 +1,13 @@ +import datetime import json import re from collections import OrderedDict from urllib.parse import parse_qs, urlparse import bleach +import pytz from django.conf import settings from django.contrib.auth import get_user_model -from django.core.cache import cache from django.core.exceptions import ValidationError as DjangoValidationError from django.core.validators import URLValidator from django.db import models @@ -21,8 +22,6 @@ AdminNote, Advisor, ApplicationCommittee, - ApplicationCycle, - ApplicationExtension, ApplicationMultipleChoice, ApplicationQuestion, ApplicationQuestionResponse, @@ -97,28 +96,6 @@ def save(self): return super().save() -class ApplicationCycleSerializer(serializers.ModelSerializer): - class Meta: - model = ApplicationCycle - fields = ["id", "name", "start_date", "end_date", "release_date"] - - def validate(self, data): - """ - Check that start_date <= end_date <= release_date - """ - start_date = data.get("start_date") - end_date = data.get("end_date") - release_date = data.get("release_date") - - if start_date and end_date and start_date >= end_date: - raise serializers.ValidationError("Start must be before end.") - - if end_date and release_date and end_date >= release_date: - raise serializers.ValidationError("End must be before release.") - - return data - - class TagSerializer(serializers.ModelSerializer): clubs = serializers.IntegerField(read_only=True) @@ -1038,7 +1015,6 @@ class Meta: "is_favorite", "is_member", "is_subscribe", - "is_wharton", "membership_count", "recruiting_cycle", "name", @@ -2220,7 +2196,6 @@ class Meta(ClubSerializer.Meta): "terms", "owners", "officers", - "approved_on", ] @@ -2469,86 +2444,6 @@ class Meta: fields = ("text", "multiple_choice", "question_type", "question") -class ApplicationExtensionSerializer(serializers.ModelSerializer): - first_name = serializers.CharField(source="user.first_name", read_only=True) - last_name = serializers.CharField(source="user.last_name", read_only=True) - username = serializers.CharField(source="user.username", read_only=False) - graduation_year = serializers.CharField( - source="user.profile.graduation_year", read_only=True - ) - - class Meta: - model = ApplicationExtension - fields = ( - "id", - "username", - "first_name", - "last_name", - "graduation_year", - "end_time", - ) - - def create(self, validated_data): - username = validated_data.get("user").pop("username") - validated_data["user"] = get_user_model().objects.get(username=username) - - application_pk = self.context["view"].kwargs.get("application_pk") - validated_data["application"] = ClubApplication.objects.filter( - pk=application_pk - ).first() - - return super().create(validated_data) - - def update(self, instance, validated_data): - if user_field := validated_data.pop("user", None): - username = user_field.pop("username") - user = get_user_model().objects.get(username=username) - instance.user = user - return super().update(instance, validated_data) - - def validate(self, data): - username = None - if user_field := data.get("user") or not self.instance: - username = user_field.get("username") - user = get_user_model().objects.filter(username=username).first() - if not user: - raise serializers.ValidationError("Please provide a valid username!") - - application_pk = self.context["view"].kwargs.get("application_pk") - application = ClubApplication.objects.filter(pk=application_pk).first() - - if not application: - raise serializers.ValidationError("Invalid application id!") - - extension_exists = ApplicationExtension.objects.filter( - user=user, application=application - ).exists() - modify_username = not self.instance or ( - username and self.instance.user.username != username - ) - - if modify_username and extension_exists: - raise serializers.ValidationError( - "An extension for this user and application already exists!" - ) - - extension_end_time = data.get("end_time") - if ( - extension_end_time - and extension_end_time <= application.application_end_time - ): - raise serializers.ValidationError( - "Extension end time must be greater than the application end time!" - ) - - return data - - def save(self): - extension_obj = super().save() - extension_obj.send_extension_mail() - return extension_obj - - class ApplicationSubmissionSerializer(serializers.ModelSerializer): committee = ApplicationCommitteeSerializer(required=False, read_only=True) responses = ApplicationQuestionResponseSerializer( @@ -2577,6 +2472,23 @@ def get_application_link(self, obj): # cannot link to the application if the application has been deleted return "#" + def validate(self, data): + application_start_time = data["application_start_time"] + application_end_time = data["application_end_time"] + now = pytz.UTC.localize(datetime.datetime.now()) + + if now < application_start_time: + raise serializers.ValidationError( + "You cannot submit before the application has opened." + ) + + if now > application_end_time: + raise serializers.ValidationError( + "You cannot submit after the application deadline." + ) + + return data + class Meta: model = ApplicationSubmission fields = ( @@ -2588,8 +2500,6 @@ class Meta: "status", "responses", "club", - "notified", - "reason", "name", "application_link", "first_name", @@ -2598,7 +2508,6 @@ class Meta: "code", "graduation_year", ) - read_only_fields = fields class ApplicationSubmissionUserSerializer(ApplicationSubmissionSerializer): @@ -2633,10 +2542,6 @@ class ApplicationSubmissionCSVSerializer(serializers.ModelSerializer): email = serializers.CharField(source="user.email") graduation_year = serializers.CharField(source="user.profile.graduation_year") committee = serializers.SerializerMethodField("get_committee") - status = serializers.SerializerMethodField("get_status") - - def get_status(self, obj): - return dict(ApplicationSubmission.STATUS_TYPES).get(obj, "Unknown") def get_name(self, obj): """ @@ -2712,15 +2617,11 @@ class Meta: "email", "graduation_year", "committee", - "notified", - "reason", - "status", ) class ClubApplicationSerializer(ClubRouteMixin, serializers.ModelSerializer): name = serializers.SerializerMethodField("get_name") - cycle = serializers.SerializerMethodField("get_cycle") committees = ApplicationCommitteeSerializer( many=True, required=False, read_only=True ) @@ -2728,16 +2629,9 @@ class ClubApplicationSerializer(ClubRouteMixin, serializers.ModelSerializer): club = serializers.SlugRelatedField(slug_field="code", read_only=True) updated_at = serializers.SerializerMethodField("get_updated_time", read_only=True) club_image_url = serializers.SerializerMethodField("get_image_url", read_only=True) - external_url = serializers.SerializerMethodField("get_external_url") + season = serializers.CharField(read_only=True) active = serializers.SerializerMethodField("get_active", read_only=True) - def get_external_url(self, obj): - default_url = f"https://pennclubs.com/club/{obj.club.code}/application/{obj.pk}" - return obj.external_url if obj.external_url else default_url - - def get_cycle(self, obj): - return obj.application_cycle.name if obj.application_cycle else obj.season - def get_active(self, obj): now = timezone.now() return obj.application_end_time >= now @@ -2767,45 +2661,20 @@ def get_image_url(self, obj): return image.url def validate(self, data): - acceptance_template = data.get("acceptance_email", "") - rejection_template = data.get("rejection_email", "") - request = self.context["request"].data + application_start_time = data["application_start_time"] + application_end_time = data["application_end_time"] + result_release_time = data["result_release_time"] - if "committees" in request and data["application_start_time"] < timezone.now(): + if application_start_time > application_end_time: raise serializers.ValidationError( - "You cannot edit committees once the application is open" + "Your application start time must be less than the end time!" ) - if not ClubApplication.validate_template( - acceptance_template - ) or not ClubApplication.validate_template(rejection_template): + if application_end_time > result_release_time: raise serializers.ValidationError( - "Your application email templates contain invalid variables!" + "Your application end time must be less than the result release time!" ) - if all( - field in data - for field in [ - "application_start_time", - "application_end_time", - "result_release_time", - ] - ): - application_start_time = data["application_start_time"] - application_end_time = data["application_end_time"] - result_release_time = data["result_release_time"] - - if application_start_time > application_end_time: - raise serializers.ValidationError( - "Your application start time must be less than the end time!" - ) - - if application_end_time > result_release_time: - raise serializers.ValidationError( - """Your application end time must be less than - the result release time!""" - ) - return data def save(self): @@ -2815,7 +2684,7 @@ def save(self): request = self.context["request"].data # only allow modifications to committees if the application is not yet open - now = timezone.now() + now = pytz.timezone("America/New_York").localize(datetime.datetime.now()) if "committees" in request and application_obj.application_start_time > now: committees = map( lambda x: x["value"] if "value" in x else x["name"], @@ -2825,17 +2694,16 @@ def save(self): application=application_obj ) # nasty hack for idempotency - prev_committee_names = prev_committees.values("name") for prev_committee in prev_committees: if prev_committee.name not in committees: prev_committee.delete() + prev_committee_names = prev_committees.values("name") for name in committees: if name not in prev_committee_names: ApplicationCommittee.objects.create( name=name, application=application_obj, ) - cache.delete(f"clubapplication:{application_obj.id}") return application_obj @@ -2843,14 +2711,11 @@ class Meta: model = ClubApplication fields = ( "id", + "season", "active", "name", - "cycle", - "acceptance_email", - "rejection_email", "application_start_time", "application_end_time", - "application_end_time_exception", "result_release_time", "external_url", "committees", @@ -2869,18 +2734,6 @@ class Meta(ClubApplicationSerializer.Meta): pass -class ManagedClubApplicationSerializer(ClubApplicationSerializer): - name = serializers.CharField(required=False, allow_blank=True) - - class Meta(ClubApplicationSerializer.Meta): - read_only_fields = ( - "external_url", - "application_start_time", - "application_end_time", - "result_release_time", - ) - - class NoteSerializer(ManyToManySaveMixin, serializers.ModelSerializer): creator = serializers.HiddenField(default=serializers.CurrentUserDefault()) creating_club = serializers.SlugRelatedField( diff --git a/backend/clubs/urls.py b/backend/clubs/urls.py index 7da672904..1a740ccb2 100644 --- a/backend/clubs/urls.py +++ b/backend/clubs/urls.py @@ -4,7 +4,6 @@ from clubs.views import ( AdminNoteViewSet, AdvisorViewSet, - ApplicationExtensionViewSet, ApplicationQuestionViewSet, ApplicationSubmissionUserViewSet, ApplicationSubmissionViewSet, @@ -52,7 +51,6 @@ UserZoomAPIView, WhartonApplicationAPIView, WhartonApplicationStatusAPIView, - WhartonCyclesView, YearViewSet, email_preview, ) @@ -81,12 +79,6 @@ router.register( r"external/members/(?P.+)", ExternalMemberListViewSet, basename="external" ) -router.register( - r"cycles", WhartonCyclesView, basename="wharton-applications-create", -) -router.register( - r"whartonapplications", WhartonApplicationAPIView, basename="wharton", -) router.register(r"submissions", ApplicationSubmissionUserViewSet, basename="submission") clubs_router = routers.NestedSimpleRouter(router, r"clubs", lookup="club") @@ -123,10 +115,6 @@ basename="club-application-submissions", ) -applications_router.register( - r"extensions", ApplicationExtensionViewSet, basename="club-application-extensions" -) - router.register(r"booths", ClubBoothsViewSet, basename="club-booth") urlpatterns = [ @@ -165,6 +153,11 @@ MeetingZoomWebhookAPIView.as_view(), name="webhooks-meeting", ), + path( + r"whartonapplications/", + WhartonApplicationAPIView.as_view(), + name="wharton-applications", + ), path( r"whartonapplications/status/", WhartonApplicationStatusAPIView.as_view(), diff --git a/backend/clubs/views.py b/backend/clubs/views.py index 931d3ad1c..f8e3bcefd 100644 --- a/backend/clubs/views.py +++ b/backend/clubs/views.py @@ -11,7 +11,6 @@ from functools import wraps from urllib.parse import urlparse -import pandas as pd import pytz import qrcode import requests @@ -21,11 +20,9 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission -from django.core import mail from django.core.cache import cache from django.core.exceptions import ValidationError from django.core.files.uploadedfile import UploadedFile -from django.core.mail import EmailMultiAlternatives from django.core.management import call_command, get_commands, load_command_class from django.core.serializers.json import DjangoJSONEncoder from django.core.validators import validate_email @@ -39,21 +36,18 @@ Q, TextField, ) -from django.db.models.expressions import Value -from django.db.models.functions import SHA1, Concat, Lower, Trunc +from django.db.models.expressions import RawSQL, Value +from django.db.models.functions import SHA1, Lower, Trunc +from django.db.models.functions.text import Concat from django.db.models.query import prefetch_related_objects from django.http import HttpResponse from django.shortcuts import get_object_or_404, render from django.template.loader import render_to_string from django.utils import timezone -from django.utils.decorators import method_decorator from django.utils.text import slugify -from django.views.decorators.cache import cache_page -from django.views.decorators.vary import vary_on_cookie from ics import Calendar as ICSCal from ics import Event as ICSEvent from ics import parse as ICSParse -from jinja2 import Template from options.models import Option from rest_framework import filters, generics, parsers, serializers, status, viewsets from rest_framework.decorators import action @@ -71,8 +65,6 @@ from clubs.models import ( AdminNote, Advisor, - ApplicationCycle, - ApplicationExtension, ApplicationMultipleChoice, ApplicationQuestion, ApplicationQuestionResponse, @@ -130,8 +122,6 @@ from clubs.serializers import ( AdminNoteSerializer, AdvisorSerializer, - ApplicationCycleSerializer, - ApplicationExtensionSerializer, ApplicationQuestionResponseSerializer, ApplicationQuestionSerializer, ApplicationSubmissionCSVSerializer, @@ -156,7 +146,6 @@ FavoriteWriteSerializer, FavouriteEventSerializer, MajorSerializer, - ManagedClubApplicationSerializer, MembershipInviteSerializer, MembershipRequestSerializer, MembershipSerializer, @@ -1032,7 +1021,13 @@ class ClubViewSet(XLSXFormatterMixin, viewsets.ModelViewSet): """ queryset = ( - Club.objects.all().prefetch_related("tags").order_by("-favorite_count", "name") + Club.objects.all() + .annotate( + favorite_count=Count("favorite", distinct=True), + membership_count=Count("membership", distinct=True, filter=Q(active=True)), + ) + .prefetch_related("tags") + .order_by("-favorite_count", "name") ) permission_classes = [ClubPermission | IsSuperuser] filter_backends = [filters.SearchFilter, ClubsSearchFilter, ClubsOrderingFilter] @@ -1157,8 +1152,6 @@ def upload(self, request, *args, **kwargs): """ # ensure user is allowed to upload image club = self.get_object() - key = f"clubs:{club.id}" - cache.delete(key) # reset approval status after upload resp = upload_endpoint_helper(request, club, "file", "image", save=False) @@ -1945,54 +1938,20 @@ def check_approval_permission(self, request): "or deregistering for the SAC fair." ) - def list(self, *args, **kwargs): - """ - Return a list of all clubs. Responses cached for 1 hour - - Responses are only cached for people with specific permissions - """ - key = self.request.build_absolute_uri() - cached_object = cache.get(key) - if ( - cached_object - and not self.request.user.groups.filter(name="Approvers").exists() - ): - return Response(cached_object) - - resp = super().list(*args, **kwargs) - cache.set(key, resp.data, 60 * 60) - return resp - - def retrieve(self, *args, **kwargs): - """ - Retrieve data about a specific club. Responses cached for 1 hour - """ - key = f"clubs:{self.get_object().id}" - cached = cache.get(key) - if cached: - return Response(cached) - - resp = super().retrieve(*args, **kwargs) - cache.set(key, resp.data, 60 * 60) - return resp + def partial_update(self, request, *args, **kwargs): + self.check_approval_permission(request) + return super().partial_update(request, *args, **kwargs) def update(self, request, *args, **kwargs): - """ - Invalidate caches - """ self.check_approval_permission(request) - key = f"clubs:{self.get_object().id}" - cache.delete(key) return super().update(request, *args, **kwargs) - def partial_update(self, request, *args, **kwargs): + def list(self, request, *args, **kwargs): """ - Invalidate caches + Return a list of all clubs. + Note that some fields are removed in order to improve response time. """ - self.check_approval_permission(request) - key = f"clubs:{self.get_object().id}" - cache.delete(key) - return super().partial_update(request, *args, **kwargs) + return super().list(request, *args, **kwargs) def perform_destroy(self, instance): """ @@ -2085,10 +2044,7 @@ def get_serializer_class(self): self.request.accepted_renderer.format == "xlsx" or self.action == "fields" ): - if ( - self.request.user.has_perm("clubs.generate_reports") - or self.request.user.is_superuser - ): + if self.request.user.has_perm("clubs.generate_reports"): return ReportClubSerializer else: return ClubSerializer @@ -3989,8 +3945,9 @@ def post(self, request): meeting_id = ( request.data.get("payload", {}).get("object", {}).get("id", None) ) - regex = rf"""https?:\/\/([A-z]*\.)?zoom\.us/[^\/]*\/ - {meeting_id}(\?pwd=[A-z,0-9]*)?""" + regex = ( + rf"https?:\/\/([A-z]*.)?zoom.us/[^\/]*\/{meeting_id}(\?pwd=[A-z,0-9]*)?" + ) event = Event.objects.filter(url__regex=regex).first() participant_id = ( @@ -4931,24 +4888,12 @@ def question_response(self, *args, **kwargs): user=self.request.user, committee__isnull=False, application=application, + archived=False, ) .values_list("committee__name", flat=True) .distinct() ) - # prevent submissions outside of the open duration - now = timezone.now() - extension = application.extensions.filter(user=self.request.user).first() - end_time = ( - max(extension.end_time, application.application_end_time) - if extension - else application.application_end_time - ) - if now > end_time or now < application.application_start_time: - return Response( - {"success": False, "detail": "This application is not currently open!"} - ) - # limit applicants to 2 committees if ( committee @@ -4964,13 +4909,9 @@ def question_response(self, *args, **kwargs): submissions page""", } ) - submission, _ = ApplicationSubmission.objects.get_or_create( + submission = ApplicationSubmission.objects.create( user=self.request.user, application=application, committee=committee, ) - - key = f"applicationsubmissions:{application.id}" - cache.delete(key) - for question_pk in questions: question = ApplicationQuestion.objects.filter(pk=question_pk).first() question_type = question.question_type @@ -4989,11 +4930,9 @@ def question_response(self, *args, **kwargs): ): text = question_data.get("text", None) if text is not None and text != "": - obj, _ = ApplicationQuestionResponse.objects.update_or_create( - question=question, - submission=submission, - defaults={"text": text}, - ) + obj = ApplicationQuestionResponse.objects.create( + text=text, question=question, submission=submission, + ).save() response = Response(ApplicationQuestionResponseSerializer(obj).data) elif question_type == ApplicationQuestion.MULTIPLE_CHOICE: multiple_choice_value = question_data.get("multipleChoice", None) @@ -5001,12 +4940,13 @@ def question_response(self, *args, **kwargs): multiple_choice_obj = ApplicationMultipleChoice.objects.filter( question=question, value=multiple_choice_value ).first() - obj, _ = ApplicationQuestionResponse.objects.update_or_create( + obj = ApplicationQuestionResponse.objects.create( + multiple_choice=multiple_choice_obj, question=question, submission=submission, - defaults={"multiple_choice": multiple_choice_obj}, - ) + ).save() response = Response(ApplicationQuestionResponseSerializer(obj).data) + submission.save() return response @action(detail=False, methods=["get"]) @@ -5074,10 +5014,10 @@ def questions(self, *args, **kwargs): response = ( ApplicationQuestionResponse.objects.filter( - question=question, submission__user=self.request.user, + submission__user=self.request.user ) - .select_related("submission", "multiple_choice", "question") - .prefetch_related("question__committees", "question__multiple_choice") + .filter(question__prompt=question.prompt) + .order_by("-updated_at") .first() ) @@ -5097,199 +5037,12 @@ class ClubApplicationViewSet(viewsets.ModelViewSet): create: Create an application for the club. list: Retrieve a list of applications of the club. - - retrieve: Retrieve information about a single application - - current: Retrieve a list of active applications of the club. - - send_emails: Send out acceptance/rejection emails """ permission_classes = [ClubItemPermission | IsSuperuser] serializer_class = ClubApplicationSerializer http_method_names = ["get", "post", "put", "patch", "delete"] - def destroy(self, *args, **kwargs): - """ - Invalidate cache before deleting - """ - app = self.get_object() - key = f"clubapplication:{app.id}" - cache.delete(key) - return super().destroy(*args, **kwargs) - - def update(self, *args, **kwargs): - """ - Invalidate cache before updating - """ - app = self.get_object() - key = f"clubapplication:{app.id}" - cache.delete(key) - return super().update(*args, **kwargs) - - def retrieve(self, *args, **kwargs): - """ - Cache responses for one hour. This is what people - see when viewing an individual club's application - """ - - pk = self.kwargs["pk"] - key = f"clubapplication:{pk}" - cached = cache.get(key) - if cached: - return Response(cached) - app = self.get_object() - data = ClubApplicationSerializer(app).data - cache.set(key, data, 60 * 60) - return Response(data) - - @action(detail=True, methods=["post"]) - def send_emails(self, *args, **kwargs): - """ - Send out acceptance/rejection emails for a particular application - - Dry run will validate that all emails have nonempty variables - - Allow resend will renotify submissions that have already been emailed - --- - requestBody: - content: - application/json: - schema: - type: object - properties: - allow_resend: - type: boolean - dry_run: - type: boolean - email_type: - type: object - properties: - id: - type: string - name: - type: string - responses: - "200": - content: - application/json: - schema: - type: object - properties: - detail: - type: string - - --- - - """ - - app = self.get_object() - - # Query for recent submissions with user and committee joined - submissions = ApplicationSubmission.objects.filter( - application=app - ).select_related("user", "committee") - - dry_run = self.request.data.get("dry_run") - - if not dry_run: - # Invalidate submission viewset cache - key = f"applicationsubmissions:{app.id}" - cache.delete(key) - - email_type = self.request.data.get("email_type")["id"] - - subject = f"Application Update for {app.name}" - n, skip = 0, 0 - - allow_resend = self.request.data.get("allow_resend") - - acceptance_template = Template(app.acceptance_email) - rejection_template = Template(app.rejection_email) - - mass_emails = [] - for submission in submissions: - if ( - (not allow_resend and submission.notified) - or submission.status == ApplicationSubmission.PENDING - or not (submission.reason and submission.user.email) - ): - skip += 1 - continue - elif ( - submission.status == ApplicationSubmission.ACCEPTED - and email_type == "acceptance" - ): - template = acceptance_template - elif ( - email_type == "rejection" - and submission.status != ApplicationSubmission.ACCEPTED - ): - template = rejection_template - else: - continue - - data = { - "reason": submission.reason, - "name": submission.user.first_name or "", - "committee": submission.committee.name if submission.committee else "", - } - - html_content = template.render(data) - text_content = html_to_text(html_content) - - contact_email = app.club.email - - msg = EmailMultiAlternatives( - subject, - text_content, - settings.FROM_EMAIL, - [submission.user.email], - reply_to=[contact_email], - ) - msg.attach_alternative(html_content, "text/html") - mass_emails.append(msg) - - if not dry_run: - submission.notified = True - n += 1 - - if not dry_run: - with mail.get_connection() as conn: - conn.send_messages(mass_emails) - ApplicationSubmission.objects.bulk_update(submissions, ["notified"]) - - dry_run_msg = "Would have sent" if dry_run else "Sent" - return Response( - { - "detail": f"{dry_run_msg} emails to {n} people, " - f"skipping {skip} due to one of (already notified, no reason, no email)" - } - ) - - @action(detail=False, methods=["get"]) - def current(self, *args, **kwargs): - """ - Return the ongoing application(s) for this club - --- - responses: - "200": - content: - application/json: - schema: - allOf: - - $ref: "#/components/schemas/ClubApplication" - --- - """ - qs = self.get_queryset().prefetch_related("extensions") - now = timezone.now() - user = self.request.user - q = Q(application_end_time__gte=now) - if user.is_authenticated: - q |= Q(extensions__end_time__gte=now, extensions__user=user) - - return Response(ClubApplicationSerializer(qs.filter(q), many=True).data) - @action(detail=True, methods=["post"]) def duplicate(self, *args, **kwargs): """ @@ -5308,7 +5061,6 @@ def duplicate(self, *args, **kwargs): now = timezone.now() clone.application_start_time = now + datetime.timedelta(days=1) clone.application_end_time = now + datetime.timedelta(days=30) - clone.result_release_time = now + datetime.timedelta(days=40) clone.external_url = ( f"https://pennclubs.com/club/{clone.club.code}/" f"application/{clone.pk}" ) @@ -5317,284 +5069,16 @@ def duplicate(self, *args, **kwargs): def get_serializer_class(self): if self.action in {"create", "update", "partial_update"}: - if "club_code" in self.kwargs: - club = ( - Club.objects.filter(code=self.kwargs["club_code"]) - .prefetch_related("badges") - .first() - ) - if club and club.is_wharton: - return ManagedClubApplicationSerializer return WritableClubApplicationSerializer return ClubApplicationSerializer def get_queryset(self): - return ( - ClubApplication.objects.filter(club__code=self.kwargs["club_code"],) - .select_related("application_cycle", "club") - .prefetch_related( - "questions__multiple_choice", "questions__committees", "committees", - ) - ) - - -class WhartonCyclesView(viewsets.ModelViewSet): - """ - get: Return information about all Wharton Council application cycles - patch: Update application cycle and WC applications with cycle - clubs: list clubs with cycle - add_clubs: add clubs to cycle - remove_clubs_from_all: remove clubs from all cycles - """ - - permission_classes = [WhartonApplicationPermission | IsSuperuser] - # Designed to support partial updates, but ModelForm sends all fields here - http_method_names = ["get", "post", "patch", "delete"] - serializer_class = ApplicationCycleSerializer - - def get_queryset(self): - return ApplicationCycle.objects.all().order_by("end_date") - - def update(self, *args, **kwargs): - """ - Updates times for all applications with cycle - """ - applications = ClubApplication.objects.filter( - application_cycle=self.get_object() - ) - str_start_date = self.request.data.get("start_date").replace("T", " ") - str_end_date = self.request.data.get("end_date").replace("T", " ") - str_release_date = self.request.data.get("release_date").replace("T", " ") - time_format = "%Y-%m-%d %H:%M:%S%z" - start = ( - datetime.datetime.strptime(str_start_date, time_format) - if str_start_date - else self.get_object().start_date - ) - end = ( - datetime.datetime.strptime(str_end_date, time_format) - if str_end_date - else self.get_object().end_date - ) - release = ( - datetime.datetime.strptime(str_release_date, time_format) - if str_release_date - else self.get_object().release_date - ) - for app in applications: - app.application_start_time = start - if app.application_end_time_exception: - continue - app.application_end_time = end - app.result_release_time = release - f = ["application_start_time", "application_end_time", "result_release_time"] - ClubApplication.objects.bulk_update(applications, f) - return super().update(*args, **kwargs) - - @action(detail=True, methods=["GET"]) - def get_clubs(self, *args, **kwargs): - """ - Retrieve clubs associated with given cycle - --- - requestBody: - content: {} - responses: - "200": - content: {} - --- - """ - cycle = self.get_object() - - return Response( - ClubApplication.objects.filter(application_cycle=cycle) - .select_related("club") - .values("club__name", "club__code") - ) - - @action(detail=True, methods=["PATCH"]) - def edit_clubs(self, *args, **kwargs): - """ - Edit clubs associated with given cycle - --- - requestBody: - content: - application/json: - schema: - type: object - properties: - clubs: - type: array - items: - type: string - responses: - "200": - content: {} - --- - - """ - cycle = self.get_object() - club_codes = self.request.data.get("clubs") - start = cycle.start_date - end = cycle.end_date - release = cycle.release_date - - # Some apps get deleted - ClubApplication.objects.filter(application_cycle=cycle).exclude( - club__code__in=club_codes - ).delete() - - # Some apps need to be created - use the default Wharton Template - prompt_one = ( - "Tell us about a time you took " "initiative or demonstrated leadership" - ) - prompt_two = "Tell us about a time you faced a challenge and how you solved it" - prompt_three = "Tell us about a time you collaborated well in a team" - created_apps_clubs = ( - ClubApplication.objects.filter( - application_cycle=cycle, club__code__in=club_codes - ) - .select_related("club") - .values_list("club__code", flat=True) - ) - creation_pending_clubs = Club.objects.filter( - code__in=set(club_codes) - set(created_apps_clubs) - ) - - for club in creation_pending_clubs: - name = f"{club.name} Application" - most_recent = ( - ClubApplication.objects.filter(club=club) - .order_by("-created_at") - .first() - ) - - if most_recent: - # If an application for this club exists, clone it - application = most_recent.make_clone() - application.application_start_time = start - application.application_end_time = end - application.result_release_time = release - application.application_cycle = cycle - application.is_wharton_council = True - application.external_url = ( - f"https://pennclubs.com/club/{club.code}/" - f"application/{application.pk}" - ) - application.save() - else: - # Otherwise, start afresh - application = ClubApplication.objects.create( - name=name, - club=club, - application_start_time=start, - application_end_time=end, - result_release_time=release, - application_cycle=cycle, - is_wharton_council=True, - ) - external_url = ( - f"https://pennclubs.com/club/{club.code}/" - f"application/{application.pk}" - ) - application.external_url = external_url - application.save() - prompt = ( - "Choose one of the following prompts for your personal statement" - ) - prompt_question = ApplicationQuestion.objects.create( - question_type=ApplicationQuestion.MULTIPLE_CHOICE, - application=application, - prompt=prompt, - ) - ApplicationMultipleChoice.objects.create( - value=prompt_one, question=prompt_question - ) - ApplicationMultipleChoice.objects.create( - value=prompt_two, question=prompt_question - ) - ApplicationMultipleChoice.objects.create( - value=prompt_three, question=prompt_question - ) - ApplicationQuestion.objects.create( - question_type=ApplicationQuestion.FREE_RESPONSE, - prompt="Answer the prompt you selected", - word_limit=150, - application=application, - ) + return ClubApplication.objects.filter(club__code=self.kwargs["club_code"]) - return Response([]) - @action(detail=False, methods=["post"]) - def add_clubs_to_exception(self, *args, **kwargs): - """ - Exempt selected clubs from application cycle deadline - --- - requestBody: - content: - application/json: - schema: - type: object - properties: - clubs: - type: array - items: - type: object - properties: - id: - type: integer - application_end_time: - type: string - responses: - "200": - content: {} - --- - """ - clubs = self.request.data.get("clubs") - apps = [] - for club in clubs: - app = ClubApplication.objects.get(pk=club["id"]) - apps.append(app) - app.application_end_time = club["end_date"] - app.application_end_time_exception = True - ClubApplication.objects.bulk_update( - apps, ["application_end_time", "application_end_time_exception"], - ) - return Response([]) - - @action(detail=False, methods=["post"]) - def remove_clubs_from_exception(self, *args, **kwargs): - """ - Remove selected clubs from application cycle deadline exemption - --- - requestBody: - content: - application/json: - schema: - type: object - properties: - clubs: - type: array - items: - type: string - responses: - "200": - content: {} - --- - """ - club_ids = self.request.data.get("clubs", []) - apps = ClubApplication.objects.filter(pk__in=club_ids) - for app in apps: - app.application_end_time_exception = False - app.application_end_time = app.application_cycle.end_date - ClubApplication.objects.bulk_update( - apps, ["application_end_time", "application_end_time_exception"], - ) - return Response([]) - - -class WhartonApplicationAPIView(viewsets.ModelViewSet): +class WhartonApplicationAPIView(generics.ListAPIView): """ - list: Return information about all Wharton Council club applications which are + get: Return information about all Wharton Council club applications which are currently on going """ @@ -5602,37 +5086,30 @@ class WhartonApplicationAPIView(viewsets.ModelViewSet): serializer_class = ClubApplicationSerializer def get_operation_id(self, **kwargs): - return f"{kwargs['operId']} Wharton Application" + return "List Wharton applications and details" def get_queryset(self): now = timezone.now() - qs = ( - ClubApplication.objects.filter( - is_wharton_council=True, - application_start_time__lte=now, - application_end_time__gte=now, - ) - .select_related("club") - .prefetch_related( - "committees", "questions__multiple_choice", "questions__committees" - ) + qs = ClubApplication.objects.filter( + is_wharton_council=True, application_end_time__gte=now ) - # Order applications randomly for viewing (consistent and unique per user). + # randomly order Wharton Council applications by user + key = str(self.request.user.id) + + cached_qs = cache.get(key) + + if cached_qs and qs.count() == cached_qs.count(): + return cached_qs + qs = qs.annotate( - random=SHA1(Concat("name", Value(key), output_field=TextField())) - ).order_by("random") - return qs + random_id=SHA1(Concat("club", Value(key)), output_field=TextField()) + ).order_by("random_id") + cache.set(key, qs, 60) - @method_decorator(cache_page(60 * 20)) - @method_decorator(vary_on_cookie) - def list(self, *args, **kwargs): - """ - Cache responses for 20 minutes. Vary cache by user. - """ - return super().list(*args, **kwargs) + return qs class WhartonApplicationStatusAPIView(generics.ListAPIView): @@ -5648,7 +5125,23 @@ def get_operation_id(self, **kwargs): def get_queryset(self): return ( - ApplicationSubmission.objects.filter(application__is_wharton_council=True) + ApplicationSubmission.objects.filter( + application__is_wharton_council=True, + created_at__in=RawSQL( + """SELECT recent_time + FROM + (SELECT user_id, + committee_id, + application_id, + max(created_at) recent_time + FROM clubs_applicationsubmission + WHERE NOT archived + GROUP BY user_id, + committee_id, application_id) recent_subs""", + (), + ), + archived=False, + ) .annotate( annotated_name=F("application__name"), annotated_committee=F("committee__name"), @@ -5665,17 +5158,7 @@ def get_queryset(self): ) -class ApplicationExtensionViewSet(viewsets.ModelViewSet): - permission_classes = [ClubSensitiveItemPermission | IsSuperuser] - serializer_class = ApplicationExtensionSerializer - - def get_queryset(self): - return ApplicationExtension.objects.filter( - application__pk=self.kwargs["application_pk"] - ) - - -class ApplicationSubmissionViewSet(viewsets.ModelViewSet): +class ApplicationSubmissionViewSet(XLSXFormatterMixin, viewsets.ModelViewSet): """ list: List submissions for a given club application. @@ -5688,50 +5171,35 @@ class ApplicationSubmissionViewSet(viewsets.ModelViewSet): http_method_names = ["get", "post"] def get_queryset(self): - app_id = self.kwargs["application_pk"] - submissions = ( - ApplicationSubmission.objects.filter(application=app_id) - .select_related("user__profile", "committee", "application__club") - .prefetch_related( - Prefetch( - "responses", - queryset=ApplicationQuestionResponse.objects.select_related( - "multiple_choice", "question" - ), - ), - "responses__question__committees", - "responses__question__multiple_choice", - ) - ) - return submissions - - def list(self, *args, **kwargs): - """ - Manually cache responses (to support invalidation) - Responses are invalidated on status / reason updates and email sending - """ + # Use a raw SQL query to obtain the most recent (user, committee) pairs + # of application submissions for a specific application. + # Done by grouping by (user_id, commitee_id) and returning the most + # recent instance in each group, then selecting those instances app_id = self.kwargs["application_pk"] - key = f"applicationsubmissions:{app_id}" + query = f""" + SELECT * + FROM clubs_applicationsubmission + WHERE application_id = {app_id} + AND NOT archived + AND created_at in + (SELECT recent_time + FROM + (SELECT user_id, + committee_id, + max(created_at) recent_time + FROM clubs_applicationsubmission + WHERE application_id = {app_id} + AND NOT archived + GROUP BY user_id, + committee_id) recent_subs) + """ + return ApplicationSubmission.objects.raw(query) - cached = cache.get(key) - if cached is not None: - return Response(cached) - else: - serializer = self.get_serializer_class() - qs = self.get_queryset() - data = serializer(qs, many=True).data - cache.set(key, data, 60 * 60) - - return Response(data) - - @method_decorator(cache_page(60 * 60 * 2)) @action(detail=False, methods=["get"]) def export(self, *args, **kwargs): """ - Given some application submissions, export them to CSV. - - Cached for 2 hours. + Given some application submissions, export them --- requestBody: content: @@ -5745,43 +5213,6 @@ def export(self, *args, **kwargs): type: integer status: type: integer - responses: - "200": - content: - text/csv: - schema: - type: string - --- - """ - app_id = int(self.kwargs["application_pk"]) - data = ( - ApplicationSubmission.objects.filter(application=app_id) - .select_related("user__profile", "committee", "application__club") - .prefetch_related( - Prefetch( - "responses", - queryset=ApplicationQuestionResponse.objects.select_related( - "multiple_choice", "question" - ), - ), - "responses__question__committees", - "responses__question__multiple_choice", - ) - ) - df = pd.DataFrame(ApplicationSubmissionCSVSerializer(data, many=True).data) - resp = HttpResponse( - content_type="text/csv", - headers={"Content-Disposition": "attachment;filename=submissions.csv"}, - ) - df.to_csv(index=True, path_or_buf=resp) - return resp - - @action(detail=False, methods=["get"]) - def exportall(self, *args, **kwargs): - """ - Export all application submissions for a particular cycle - --- - requestBody: {} responses: "200": content: @@ -5791,17 +5222,27 @@ def exportall(self, *args, **kwargs): properties: output: type: string + --- """ - - app_id = int(self.kwargs["application_pk"]) - cycle = ClubApplication.objects.get(id=app_id).application_cycle data = ( ApplicationSubmission.objects.filter( application__is_wharton_council=True, - application__application_cycle=cycle, + created_at__in=RawSQL( + """SELECT recent_time + FROM + (SELECT user_id, + committee_id, + application_id, + max(created_at) recent_time + FROM clubs_applicationsubmission + WHERE NOT archived + GROUP BY user_id, + committee_id, application_id) recent_subs""", + (), + ), + archived=False, ) - .select_related("application", "application__application_cycle") .annotate( annotated_name=F("application__name"), annotated_committee=F("committee__name"), @@ -5843,7 +5284,7 @@ def status(self, *args, **kwargs): schema: type: object properties: - detail: + output: type: string --- @@ -5854,83 +5295,10 @@ def status(self, *args, **kwargs): status in map(lambda x: x[0], ApplicationSubmission.STATUS_TYPES) and len(submission_pks) > 0 ): - # Invalidate submission viewset cache - submissions = ApplicationSubmission.objects.filter(pk__in=submission_pks) - app_id = submissions.first().application.id if submissions.first() else None - if not app_id: - return Response({"detail": "No submissions found"}) - key = f"applicationsubmissions:{app_id}" - cache.delete(key) - - submissions.update(status=status) - - return Response( - { - "detail": f"Successfully updated submissions' {submission_pks}" - f"status {status}" - } + ApplicationSubmission.objects.filter(pk__in=submission_pks).update( + status=status ) - else: - return Response({"detail": "Invalid request"}) - - @action(detail=False, methods=["post"]) - def reason(self, *args, **kwargs): - """ - Given some application submissions, update their acceptance/rejection - reasons - --- - requestBody: - content: - application/json: - schema: - type: object - properties: - submissions: - type: array - items: - type: object - properties: - id: - type: integer - reason: - type: string - - responses: - "200": - content: - application/json: - schema: - type: object - properties: - detail: - type: string - - --- - """ - submissions = self.request.data.get("submissions", []) - pks = list(map(lambda x: x["id"], submissions)) - reasons = list(map(lambda x: x["reason"], submissions)) - - submission_objs = ApplicationSubmission.objects.filter(pk__in=pks) - - # Invalidate submission viewset cache - app_id = ( - submission_objs.first().application.id if submission_objs.first() else None - ) - if not app_id: - return Response({"detail": "No submissions found"}) - key = f"applicationsubmissions:{app_id}" - cache.delete(key) - - for idx, pk in enumerate(pks): - obj = submission_objs.filter(pk=pk).first() - if obj: - obj.reason = reasons[idx] - obj.save() - else: - return Response({"detail": "Object not found"}) - - return Response({"detail": "Successfully updated submissions' reasons"}) + return Response([]) def get_serializer_class(self): if self.request and self.request.query_params.get("format") == "xlsx": @@ -5951,26 +5319,41 @@ class ApplicationSubmissionUserViewSet(viewsets.ModelViewSet): http_method_names = ["get", "delete"] def get_queryset(self): - submissions = ( - ApplicationSubmission.objects.filter(user=self.request.user) - .select_related("user__profile", "committee", "application__club") - .prefetch_related( - Prefetch( - "responses", - queryset=ApplicationQuestionResponse.objects.select_related( - "multiple_choice", "question" - ), - ), - "responses__question__committees", - "responses__question__multiple_choice", - ) + distinct_submissions = {} + submissions = ApplicationSubmission.objects.filter( + user=self.request.user, archived=False ) - return submissions + + # only want to return the most recent (user, committee) unique submission pair + for submission in submissions: + key = (submission.application.__str__(), submission.committee.__str__()) + if key in distinct_submissions: + if distinct_submissions[key].created_at < submission.created_at: + distinct_submissions[key] = submission + else: + distinct_submissions[key] = submission + + queryset = ApplicationSubmission.objects.none() + for submission in distinct_submissions.values(): + queryset |= ApplicationSubmission.objects.filter(pk=submission.pk) + + return queryset + + def perform_destroy(self, instance): + """ + Set archived boolean to be True so that the submissions + appears to have been deleted + """ + + instance.archived = True + instance.archived_by = self.request.user + instance.archived_on = timezone.now() + instance.save() class ApplicationQuestionViewSet(viewsets.ModelViewSet): """ - create: Create a question for a club application. + create: Create a questions for a club application. list: List questions in a given club application. """ @@ -5984,54 +5367,6 @@ def get_queryset(self): application__pk=self.kwargs["application_pk"] ).order_by("precedence") - def destroy(self, *args, **kwargs): - """ - Invalidate caches before destroying - """ - app_id = self.kwargs["application_pk"] - key1 = f"applicationquestion:{app_id}" - key2 = f"clubapplication:{app_id}" - cache.delete(key1) - cache.delete(key2) - return super().destroy(*args, **kwargs) - - def create(self, *args, **kwargs): - """ - Invalidate caches before creating - """ - app_id = self.kwargs["application_pk"] - key1 = f"applicationquestion:{app_id}" - key2 = f"clubapplication:{app_id}" - cache.delete(key1) - cache.delete(key2) - return super().create(*args, **kwargs) - - def update(self, *args, **kwargs): - """ - Invalidate caches before updating - """ - app_id = self.kwargs["application_pk"] - key1 = f"applicationquestion:{app_id}" - key2 = f"clubapplication:{app_id}" - cache.delete(key1) - cache.delete(key2) - return super().update(*args, **kwargs) - - def list(self, *args, **kwargs): - """ - Manually cache responses for one hour - """ - - app_id = self.kwargs["application_pk"] - key = f"applicationquestion:{app_id}" - cached = cache.get(key) - if cached: - return Response(cached) - - data = ApplicationQuestionSerializer(self.get_queryset(), many=True).data - cache.set(key, data, 60 * 60) - return Response(data) - @action(detail=False, methods=["post"]) def precedence(self, *args, **kwargs): """ diff --git a/backend/pennclubs/settings/base.py b/backend/pennclubs/settings/base.py index e5b379dc5..96ae167b3 100644 --- a/backend/pennclubs/settings/base.py +++ b/backend/pennclubs/settings/base.py @@ -160,7 +160,7 @@ "DEFAULT_RENDERER_CLASSES": ( "rest_framework.renderers.JSONRenderer", "rest_framework.renderers.BrowsableAPIRenderer", - "drf_excel.renderers.XLSXRenderer", + "drf_renderer_xlsx.renderers.XLSXRenderer", ), "DEFAULT_SCHEMA_CLASS": "pennclubs.doc_settings.CustomAutoSchema", "DEFAULT_AUTHENTICATION_CLASSES": [ diff --git a/backend/pennclubs/settings/production.py b/backend/pennclubs/settings/production.py index dbd81fd24..6ae09c1c0 100644 --- a/backend/pennclubs/settings/production.py +++ b/backend/pennclubs/settings/production.py @@ -61,12 +61,7 @@ "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": f"redis://{REDIS_HOST}:6379/1", - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - "IGNORE_EXCEPTIONS": True, # ignore Redis connection errors - "SOCKET_CONNECT_TIMEOUT": 1, - "SOCKET_TIMEOUT": 1, - }, + "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"}, "KEY_PREFIX": "django", } } diff --git a/backend/templates/emails/application_extension.html b/backend/templates/emails/application_extension.html deleted file mode 100644 index f3aeee637..000000000 --- a/backend/templates/emails/application_extension.html +++ /dev/null @@ -1,22 +0,0 @@ - -{% extends 'emails/base.html' %} - -{% block content %} -

Application Extension for {{ application_name }}

-

Hello {{ name }},

-

You have been granted an extension for {{ application_name }} by the officers of {{ club }} on Penn Clubs:

-

The updated deadline to submit your application is {{ end_time }}. You can apply using the button below.

- Apply -{% endblock %} diff --git a/backend/templates/emails/renew.html b/backend/templates/emails/renew.html index 38d145f64..b0dbd3c31 100644 --- a/backend/templates/emails/renew.html +++ b/backend/templates/emails/renew.html @@ -12,7 +12,7 @@

Renew {{ name }} on Penn Clubs & SAC Fair Signup

Dear {{ name }} officers,

- We have opened the student group registration process for the current academic year. To be + We have opened the student group registration process for the 2020-2021 academic year. To be considered an active student group on campus, the University requires all student organizations to be registered with the Office of Student Affairs. This year, OSA has migrated the Student Groups platform from the previous system, G.O. Penn, to Penn Labs' platform, Penn Clubs. diff --git a/backend/templates/emails/renewal_reminder.html b/backend/templates/emails/renewal_reminder.html index fe337b736..a701bc094 100644 --- a/backend/templates/emails/renewal_reminder.html +++ b/backend/templates/emails/renewal_reminder.html @@ -43,14 +43,14 @@

Reminder to Renew {{ name }} on Penn Clubs & SAC Fair Signup by 8/24!

If you are logged in and do not see any clubs, reply to this email with your PennKey and club name to gain - access to re-register your club for the upcoming school year. + access to re-register your club for the 2020-2021 school year.

Follow the 5 steps listed to update your club's information. This would be the process for your organization to gain official approval from the Office of Student Affairs. The final page of the renewal process will ask whether or - not your club is interested in participating in the semesterly SAC Fair. To sign up, please simply check the box on + not your club is interested in participating in the Fall 2020 SAC Fair. To sign up, please simply check the box on this page, and your information will be sent to the SAC Fair Coordinator.

@@ -61,4 +61,4 @@

Reminder to Renew {{ name }} on Penn Clubs & SAC Fair Signup by 8/24! If you have any questions or problems regarding re-registration, please reply to this email. If you have questions specifically regarding the SAC Fair, please send an email to sacfair@sacfunded.net.

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/backend/tests/clubs/test_views.py b/backend/tests/clubs/test_views.py index 7646cc6ec..765e8a714 100644 --- a/backend/tests/clubs/test_views.py +++ b/backend/tests/clubs/test_views.py @@ -9,7 +9,6 @@ from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core import mail -from django.core.cache import cache from django.core.management import call_command from django.test import Client, TestCase from django.urls import reverse @@ -1087,7 +1086,6 @@ def test_club_create_description_sanitize_good(self): }, content_type="application/json", ) - cache.clear() self.assertIn(resp.status_code, [200, 201], resp.content) resp = self.client.get(reverse("clubs-detail", args=("penn-labs",))) @@ -2531,3 +2529,71 @@ def test_event_add_meeting(self): self.event1.refresh_from_db() self.assertIn("url", resp.data, resp.content) self.assertTrue(self.event1.url, resp.content) + + def test_zoom_webhook(self): + """ + Test that the Zoom webhook can properly parse a request sent by the Zoom API. + """ + person = self.user1 + event = self.event1 + meeting_id = "4880003126" + participant_id = "jswPTE5-StSc-kbAX6n2Rw" + join_time = "2021-01-10T20:38:49Z" + leave_time = "2021-01-10T20:42:23Z" + + req = { + "event": "meeting.participant_joined", + "payload": { + "object": { + "participant": { + "user_id": participant_id, + "join_time": join_time, + "email": person.email, + }, + "id": meeting_id, + } + }, + } + + resp = self.client.post( + reverse("webhooks-meeting"), req, content_type="application/json" + ) + self.assertIn(resp.status_code, [200, 201], resp.content) + self.assertTrue( + ZoomMeetingVisit.objects.filter( + person=person, + event=event, + meeting_id=meeting_id, + participant_id=participant_id, + join_time=join_time, + ) + ) + + req = { + "event": "meeting.participant_left", + "payload": { + "object": { + "participant": { + "user_id": participant_id, + "leave_time": leave_time, + "email": person.email, + }, + "id": meeting_id, + } + }, + } + + resp = self.client.post( + reverse("webhooks-meeting"), req, content_type="application/json" + ) + self.assertIn(resp.status_code, [200, 201], resp.content) + self.assertTrue( + ZoomMeetingVisit.objects.filter( + person=person, + event=event, + meeting_id=meeting_id, + participant_id=participant_id, + join_time=join_time, + leave_time=leave_time, + ) + ) diff --git a/frontend/components/Applications.tsx b/frontend/components/Applications.tsx index 0bc7a4b39..a5099030b 100644 --- a/frontend/components/Applications.tsx +++ b/frontend/components/Applications.tsx @@ -1,84 +1,25 @@ import { NextPageContext } from 'next' import Link from 'next/link' import React, { ReactElement } from 'react' -import LazyLoad from 'react-lazy-load' import styled from 'styled-components' import { Application } from 'types' import { doBulkLookup } from 'utils' -import { Text } from '~/components/common' +import { Card, Text } from '~/components/common' import { ClubName } from '~/components/EventPage/common' import DateInterval from '~/components/EventPage/DateInterval' -import { - ALLBIRDS_GRAY, - ANIMATION_DURATION, - BORDER_RADIUS, - CLUBS_GREY_LIGHT, - HOVER_GRAY, - mediaMaxWidth, - SM, - WHITE, -} from '~/constants' +import { mediaMaxWidth, mediaMinWidth, PHONE, WHITE } from '~/constants' -const CardWrapper = styled.div` - ${mediaMaxWidth(SM)} { - padding-top: 0; - padding-bottom: 1rem; +const ApplicationCardContainer = styled.div` + ${mediaMinWidth(PHONE)} { + max-width: 18em; + margin: 1rem; } -` - -const DescriptionWrapper = styled.p` - margin-top: 0.2rem; - color: ${CLUBS_GREY_LIGHT}; - border-top: 1.5px solid rgba(0, 0, 0, 0.05); - width: 100%; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 5; - overflow: hidden; -` - -const Description = (text) => ( -
- {text.length > 255 ? ( -
{`${text.substring(0, 255)} ...`}
- ) : ( -

{text}

- )} -
-) - -const MainInfo = styled.div` - display: flex; - flex-direction: row; -` -type CardProps = { - readonly hovering?: boolean - className?: string -} - -const Card = styled.div` - padding: 10px; - box-shadow: 0 0 0 transparent; - transition: all ${ANIMATION_DURATION}ms ease; - border-radius: ${BORDER_RADIUS}; - box-shadow: 0 0 0 ${WHITE}; - background-color: ${({ hovering }) => (hovering ? HOVER_GRAY : WHITE)}; - border: 1px solid ${ALLBIRDS_GRAY}; - justify-content: space-between; - height: auto; - cursor: pointer; - - &:hover, - &:active, - &:focus { - box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2); - } - - ${mediaMaxWidth(SM)} { - width: calc(100%); - padding: 8px; + ${mediaMaxWidth(PHONE)} { + margin: 1rem 0; } + float: left; + cursor: pointer; !important ` const Image = styled.img` @@ -88,60 +29,35 @@ const Image = styled.img` overflow: hidden; ` -const AppsContainer = styled.div` - display: flex; - flex-direction: row; - min-height: 60vh; -` - function ApplicationsPage({ whartonapplications }): ReactElement { if ('detail' in whartonapplications) { return {whartonapplications.detail} } return ( - -
- {whartonapplications != null && whartonapplications.length > 0 ? ( - whartonapplications.map((application) => ( - - - - - -
- {application.name} - -
-
- {application.club_image_url != null && - application.club_image_url !== '' && ( - - - - )} -
-
- {application.description && application.description.length && ( - - )} -
-
- -
- )) - ) : ( - No applications are currently available. - )} -
-
+ <> + {whartonapplications != null && whartonapplications.length > 0 ? ( + whartonapplications.map((application) => ( + + + + {application.club_image_url != null && + application.club_image_url !== '' && ( + + )} + + {application.name} + + + + )) + ) : ( + No applications are currently available. + )} + ) } diff --git a/frontend/components/ClubEditPage/ApplicationsCard.tsx b/frontend/components/ClubEditPage/ApplicationsCard.tsx index 1702c39a5..587d733be 100644 --- a/frontend/components/ClubEditPage/ApplicationsCard.tsx +++ b/frontend/components/ClubEditPage/ApplicationsCard.tsx @@ -11,7 +11,6 @@ import { } from '../../utils/branding' import { Icon, Modal, Text } from '../common' import { - ApplicationUpdateTextField, CheckboxField, CreatableMultipleSelectField, DateTimeField, @@ -263,23 +262,14 @@ export default function ApplicationsCard({ club }: Props): ReactElement { ))} - {!club.is_wharton && ( - - TIP: To copy over your application from last semester, please - click duplicate on the application from the season that you - would like to copy over and refresh the page. You can then edit this - application as you please. - - )} - - If your club is affiliated with the Wharton Council Centralised - Application, please note that editable applications will be provisioned - by the system administrator.{' '} + TIP: To copy over your application from last semester, please + click duplicate on the application from the season that you + would like to copy over and refresh the page. You can then edit this + application as you please. { @@ -326,25 +316,19 @@ export default function ApplicationsCard({ club }: Props): ReactElement { name="application_start_time" as={DateTimeField} required={true} - helpText={`The date when your application opens. ${ - club.is_wharton ? 'Read-only.' : '' - }`} + helpText="The date when your application opens." /> -

Congratulations {{ name }}! You've been accepted to {{ committee }} because {{reason}}!

" - } - helpText={`Acceptance email for your ${OBJECT_NAME_SINGULAR}.`} - /> -

Sorry {{ name }}, You've been rejected because {{ reason }}!

" - } - helpText={`Rejection email for your ${OBJECT_NAME_SINGULAR}.`} - /> } confirmDeletion={true} tableFields={[ { name: 'name', label: 'Name' }, - { name: 'cycle', label: 'Cycle' }, + { name: 'season', label: 'Season' }, { name: 'id', label: 'Edit', @@ -397,16 +365,14 @@ export default function ApplicationsCard({ club }: Props): ReactElement { Questions ) : ( - !club.is_wharton && ( - - ) + )} - - {submitMessage !== null && ( -
- {submitMessage} -
- )} - - )} - - - ) -} - -const ReasonModal = (props: { - submissions: Array | null - club: string - application: Application | null - updateSubmissions: (s: { name: string }) => void -}): ReactElement => { - const { submissions, club, application, updateSubmissions } = props - const [submitMessage, setSubmitMessage] = useState< - string | ReactElement | null - >(null) - const initialValues = {} - return ( - - { - const data_: { id: number; reason: string }[] = [] - for (const [key, value] of Object.entries(data)) { - data_.push({ id: Number(key), reason: value }) - } - updateSubmissions(data) - doApiRequest( - `/clubs/${club}/applications/${application?.id}/submissions/reason/?format=json`, - { - method: 'POST', - body: { submissions: data_ }, - }, - ).then((response) => { - response.json().then((data) => { - setSubmitMessage(data.detail) - }) - }) - }} - > - {(props) => ( -
- - Update reasons for selected{' '} - {submissions != null && submissions[0] != null - ? submissions[0].status - : null}{' '} - applicants - - {submissions != null - ? submissions.map((data) => { - return ( - data != null && ( -
- -
- ) - ) - }) - : null} - - {submitMessage !== null && ( -
- {submitMessage} -
- )} -
- )} -
) } @@ -401,17 +185,12 @@ export default function ApplicationsPage({ [key: number]: Array }>([]) const [showModal, setShowModal] = useState(false) - const [showNotifModal, setShowNotifModal] = useState(false) - const [showReasonModal, setShowReasonModal] = useState(false) const [ currentSubmission, setCurrentSubmission, ] = useState(null) const [pageIndex, setPageIndex] = useState(0) const [statusToggle, setStatusToggle] = useState(false) - const [categoriesSelectAll, setCategoriesSelectAll] = useState>( - [], - ) useEffect(() => { doApiRequest(`/clubs/${club.code}/applications/?format=json`, { @@ -421,10 +200,7 @@ export default function ApplicationsPage({ .then((applications) => { if (applications.length !== 0) { setApplications(applications) - setCurrentApplication({ - ...applications[0], - name: format_app_name(applications[0]), - }) + setCurrentApplication(applications[0]) } }) }, []) @@ -465,11 +241,6 @@ export default function ApplicationsPage({ const [selectedSubmissions, setSelectedSubmissions] = useState>( [], ) - - const [submitMessage, setSubmitMessage] = useState< - string | ReactElement | null - >(null) - const [status, setStatus] = useState( ApplicationStatusType.Pending, ) @@ -495,17 +266,10 @@ export default function ApplicationsPage({ { label: 'First Name', name: 'first_name' }, { label: 'Last Name', name: 'last_name' }, { label: 'Email', name: 'email' }, + { label: 'Graduation Year', name: 'graduation_year' }, { label: 'Committee', name: 'committee' }, + { label: 'Submitted', name: 'created_at' }, { label: 'Status', name: 'status' }, - { label: 'Graduation Year', name: 'graduation_year' }, - ] - - const extensionTableFields = [ - { label: 'First Name', name: 'first_name' }, - { label: 'Last Name', name: 'last_name' }, - { label: 'Username', name: 'username' }, - { label: 'Graduation Year', name: 'graduation_year' }, - { label: 'Extension End Time', name: 'end_time' }, ] const columns = useMemo( @@ -517,16 +281,6 @@ export default function ApplicationsPage({ [responseTableFields], ) - const format_app_name: (application: Application) => any = (application) => ( - - {application.name} {' - '} - - {application.cycle || - getSemesterFromDate(application.application_end_time)} - - - ) - return ( <> Applications @@ -537,31 +291,22 @@ export default function ApplicationsPage({ setClubsSelectedMembership([...e])} - value={clubsSelectedMembership} - options={clubOptionsMembership} - isMulti - isClearable={false} - backspaceRemovesValue={false} - /> - - - - - - } - - )} - - - {extensionsCycle && extensionsCycle.name && ( - <> - - Individual Club Extensions for {extensionsCycle.name} - -
- - - - - - - - - - - {clubsExtensions.map((club) => ( - - - - - - ))} - {clubsExtensions.length < 10 && ( -
- )} -
-
ClubEnd DateException
-

{club.clubName}

-
- { - club.endDate = date - club.changed = true - setClubsExtensions([...clubsExtensions]) - }} - /> - - { - club.exception = e.target.checked - club.changed = true - setClubsExtensions([...clubsExtensions]) - }} - checked={ - club.exception != null ? club.exception : false - } - /> -
-
-
- - - )} -
- - ) -} - -export default WhartonApplicationCycles diff --git a/frontend/components/Settings/WhartonApplicationStatus.tsx b/frontend/components/Settings/WhartonApplicationStatus.tsx index 39c141d18..08f468aef 100644 --- a/frontend/components/Settings/WhartonApplicationStatus.tsx +++ b/frontend/components/Settings/WhartonApplicationStatus.tsx @@ -170,18 +170,6 @@ const WhartonApplicationStatus = ({ ApplicationStatus[] | { detail: string } | null >(initialStatuses ?? null) - function downloadData(statuses) { - const dataStr = - 'data:text/json;charset=utf-8,' + - encodeURIComponent(JSON.stringify(statuses, null, 2)) - const downloadAnchorNode = document.createElement('a') - downloadAnchorNode.setAttribute('href', dataStr) - downloadAnchorNode.setAttribute('download', 'applicationStatuses.json') - document.body.appendChild(downloadAnchorNode) - downloadAnchorNode.click() - downloadAnchorNode.remove() - } - if (statuses == null) { return } @@ -199,9 +187,6 @@ const WhartonApplicationStatus = ({ registered {OBJECT_NAME_PLURAL} for an {FAIR_NAME} fair. Only users with the required permissions can view this page. -
({ diff --git a/frontend/components/Submissions.tsx b/frontend/components/Submissions.tsx index 87b5ade21..b78276f64 100644 --- a/frontend/components/Submissions.tsx +++ b/frontend/components/Submissions.tsx @@ -163,18 +163,12 @@ function SubmissionsPage({