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 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..+)", 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 }}
- 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 @@
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 @@{text}
- )} -Congratulations {{ name }}! You've been accepted to {{ committee }} because {{reason}}!