diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml
index 0673849..721911c 100644
--- a/.github/workflows/backend.yml
+++ b/.github/workflows/backend.yml
@@ -1,158 +1,73 @@
name: Backend CI
on:
- push:
- paths:
- - "backend/**"
- - ".github/workflows/backend.yml"
- workflow_dispatch:
-
-env:
- IMAGE_NAME_PREFIX: ghcr.io/pythonbrasil/pybr25-site
- IMAGE_NAME_SUFFIX: backend
- PYTHON_VERSION: "3.11"
+ workflow_call:
+ inputs:
+ base-tag:
+ required: true
+ type: string
+ image-name-prefix:
+ required: true
+ type: string
+ image-name-suffix:
+ required: true
+ type: string
+ python-version:
+ required: true
+ type: string
+ plone-version:
+ required: true
+ type: string
+ working-directory:
+ required: false
+ type: string
+ default: backend
jobs:
- meta:
- runs-on: ubuntu-latest
- outputs:
- PLONE_VERSION: ${{ steps.vars.outputs.PLONE_VERSION }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set Env Vars
- id: vars
- run: |
- echo "PLONE_VERSION=$(cat backend/version.txt)" >> $GITHUB_OUTPUT
-
- black:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout codebase
- uses: actions/checkout@v4
-
- - name: Run check
- uses: plone/code-analysis-action@v2
- with:
- base_dir: 'backend'
- check: 'black'
-
- flake8:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout codebase
- uses: actions/checkout@v4
-
- - name: Run check
- uses: plone/code-analysis-action@v2
- with:
- base_dir: 'backend'
- check: 'flake8'
-
- isort:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout codebase
- uses: actions/checkout@v4
-
- - name: Run check
- uses: plone/code-analysis-action@v2
- with:
- base_dir: 'backend'
- check: 'isort'
-
- zpretty:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout codebase
- uses: actions/checkout@v4
-
- - name: Run check
- uses: plone/code-analysis-action@v2
- with:
- base_dir: 'backend'
- check: 'zpretty'
-
- tests:
- runs-on: ubuntu-latest
+ lint:
+ name: "Backend: Lint"
+ uses: plone/meta/.github/workflows/backend-lint.yml@2.x
+ with:
+ python-version: ${{ inputs.python-version }}
+ plone-version: ${{ inputs.plone-version }}
+ working-directory: ${{ inputs.working-directory }}
+
+ test:
+ name: "Backend: Test"
+ uses: plone/meta/.github/workflows/backend-pytest.yml@2.x
+ with:
+ python-version: ${{ inputs.python-version }}
+ plone-version: ${{ inputs.plone-version }}
+ working-directory: ${{ inputs.working-directory }}
+
+ coverage:
+ name: "Backend: Test"
+ uses: plone/meta/.github/workflows/backend-pytest-coverage.yml@2.x
needs:
- - meta
- defaults:
- run:
- working-directory: ./backend
-
- steps:
- - uses: actions/checkout@v4
-
- - name: Setup Plone ${{ needs.meta.outputs.PLONE_VERSION }} with Python ${{ env.PYTHON_VERSION }}
- uses: plone/setup-plone@v3.0.0
- with:
- python-version: ${{ env.PYTHON_VERSION }}
- plone-version: ${{ needs.meta.outputs.PLONE_VERSION }}
-
- - name: Install package
- run: |
- pip install mxdev
- mxdev -c mx.ini
- pip install -r requirements-mxdev.txt
-
- - name: Run tests
- run: |
- pytest --disable-warnings tests
+ - test
+ with:
+ python-version: ${{ inputs.python-version }}
+ plone-version: ${{ inputs.plone-version }}
+ working-directory: ${{ inputs.working-directory }}
release:
- runs-on: ubuntu-latest
+ name: "Backend: Build and publish Container Image"
+ uses: plone/meta/.github/workflows/container-image-build-push.yml@2.x
needs:
- - black
- - flake8
- - isort
- - zpretty
- - tests
+ - lint
+ - coverage
permissions:
contents: read
packages: write
-
- steps:
-
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Docker meta
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: |
- ${{ env.IMAGE_NAME_PREFIX }}-${{ env.IMAGE_NAME_SUFFIX }}
- labels: |
- org.label-schema.docker.cmd=docker run -d -p 8080:8080 ${{ env.IMAGE_NAME_PREFIX }}-${{ env.IMAGE_NAME_SUFFIX }}:latest
- flavor:
- latest=false
- tags: |
- type=ref,event=branch
- type=sha
- type=raw,value=latest,enable={{is_default_branch}}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Login to Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Build and push
- uses: docker/build-push-action@v5
- with:
- platforms: linux/amd64
- context: backend
- file: backend/Dockerfile
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
+ with:
+ base-tag: ${{ inputs.base-tag }}
+ image-name-prefix: ${{ inputs.image-name-prefix }}
+ image-name-suffix: ${{ inputs.image-name-suffix }}
+ working-directory: ${{ inputs.working-directory }}
+ build-args: |
+ PLONE_VERSION=${{ inputs.plone-version }}
+ push: ${{ github.event_name != 'pull_request' }}
+ secrets:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml
new file mode 100644
index 0000000..f3d2a42
--- /dev/null
+++ b/.github/workflows/changelog.yml
@@ -0,0 +1,135 @@
+name: Changelog
+on:
+ pull_request:
+ types: [assigned, opened, synchronize, reopened, labeled, unlabeled]
+ branches:
+ - main
+
+env:
+ NODE_VERSION: 22.x
+ ADDON_NAME: volto-pythonbrasil-site
+ BASE_BRANCH: main
+
+jobs:
+ config:
+ runs-on: ubuntu-latest
+ outputs:
+ backend: ${{ steps.filter.outputs.backend }}
+ frontend: ${{ steps.filter.outputs.frontend }}
+ repository: ${{ steps.filter.outputs.repository }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - uses: dorny/paths-filter@v3.0.2
+ id: filter
+ with:
+ filters: |
+ backend:
+ - 'backend/**'
+ repository:
+ - '.github/**'
+ - '.vscode/**'
+ - 'devops/**'
+ - 'docs/**'
+ - 'docker-compose.yml'
+ - 'README.md'
+ frontend:
+ - 'frontend/**'
+
+ backend:
+ if: ${{ needs.config.outputs.backend == 'true' }}
+ runs-on: ubuntu-latest
+ needs:
+ - config
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ # Fetch all history
+ fetch-depth: '0'
+
+ - name: Install pipx
+ run: pip install towncrier
+
+ - name: Check for presence of a Change Log fragment (only pull requests)
+ if: github.event_name == 'pull_request'
+ run: |
+ # Fetch the pull request' base branch so towncrier will be able to
+ # compare the current branch with the base branch.
+ # Source: https://github.com/actions/checkout/#fetch-all-branches.
+ git fetch --no-tags origin ${BASE_BRANCH}
+ towncrier check --compare-with origin/${{ env.BASE_BRANCH }} --config backend/pyproject.toml --dir backend/
+
+ frontend:
+ if: ${{ needs.config.outputs.frontend == 'true' }}
+ runs-on: ubuntu-latest
+ needs:
+ - config
+ defaults:
+ run:
+ working-directory: ./frontend
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ # Fetch all history
+ fetch-depth: '0'
+
+ - name: Install pipx
+ run: pip install towncrier
+
+ - name: Use Node.js ${{ env.NODE_VERSION }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Enable corepack
+ run: npm i -g corepack@latest && corepack enable
+
+ - name: Get pnpm store directory
+ shell: bash
+ run: |
+ echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
+
+ - uses: actions/cache@v4
+ name: Setup pnpm cache
+ with:
+ path: ${{ env.STORE_PATH }}
+ key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ ${{ runner.os }}-pnpm-store-
+
+ - name: Install dependencies
+ run: make install
+
+ - name: Check for presence of a Change Log fragment (only pull requests)
+ if: github.event_name == 'pull_request'
+ run: |
+ # Fetch the pull request' base branch so towncrier will be able to
+ # compare the current branch with the base branch.
+ # Source: https://github.com/actions/checkout/#fetch-all-branches.
+ git fetch --no-tags origin ${BASE_BRANCH}
+ cd ..
+ towncrier check --compare-with origin/${{ env.BASE_BRANCH }} --config frontend/packages/${{ env.ADDON_NAME }}/towncrier.toml --dir frontend/packages/${{ env.ADDON_NAME }}
+
+ repository:
+ if: ${{ needs.config.outputs.repository == 'true' }}
+ runs-on: ubuntu-latest
+ needs:
+ - config
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ # Fetch all history
+ fetch-depth: '0'
+
+ - name: Install pipx
+ run: pip install towncrier
+
+ - name: Check for presence of a Change Log fragment (only pull requests)
+ if: github.event_name == 'pull_request'
+ run: |
+ # Fetch the pull request' base branch so towncrier will be able to
+ # compare the current branch with the base branch.
+ # Source: https://github.com/actions/checkout/#fetch-all-branches.
+ git fetch --no-tags origin ${BASE_BRANCH}
+ towncrier check --compare-with origin/${{ env.BASE_BRANCH }} --config towncrier.toml --dir .
diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml
new file mode 100644
index 0000000..a2e209d
--- /dev/null
+++ b/.github/workflows/config.yml
@@ -0,0 +1,136 @@
+name: "VLT: Compute Config variables"
+
+on:
+ workflow_call:
+ inputs:
+ environment:
+ required: false
+ type: string
+ default: "2025.pythonbrasil.org.br"
+ image-name-prefix:
+ required: false
+ type: string
+ default: "ghcr.io/pythonbrasil/pybr25-site"
+ node-version:
+ required: false
+ type: string
+ default: "22.x"
+ python-version:
+ required: false
+ type: string
+ default: "3.12"
+ outputs:
+ acceptance:
+ description: "Flag reporting if we should run the acceptance jobs"
+ value: ${{ jobs.config.outputs.acceptance }}
+ backend:
+ description: "Flag reporting if we should run the backend jobs"
+ value: ${{ jobs.config.outputs.backend }}
+ devops:
+ description: "Flag reporting if we should run the devops jobs"
+ value: ${{ jobs.config.outputs.devops }}
+ docs:
+ description: "Flag reporting if we should run the docs jobs"
+ value: ${{ jobs.config.outputs.docs }}
+ frontend:
+ description: "Flag reporting if we should run the frontend jobs"
+ value: ${{ jobs.config.outputs.frontend }}
+ varnish:
+ description: "Flag reporting if we should run the varnish jobs"
+ value: ${{ jobs.config.outputs.varnish }}
+ base-tag:
+ description: "Base tag to be used when creating container images"
+ value: ${{ jobs.config.outputs.base-tag }}
+ image-name-prefix:
+ description: "Image name prefix for container images"
+ value: ${{ inputs.image-name-prefix }}
+ node-version:
+ description: "Node version to be used"
+ value: ${{ inputs.node-version }}
+ python-version:
+ description: "Python version to be used"
+ value: ${{ inputs.python-version }}
+ plone-version:
+ description: "Plone version to be used"
+ value: ${{ jobs.config.outputs.plone-version }}
+ volto-version:
+ description: "Volto version to be used"
+ value: ${{ jobs.config.outputs.volto-version }}
+ environment:
+ description: "GitHub environment"
+ value: ${{ jobs.config.outputs.environment }}
+ stack-name:
+ description: "Stack name"
+ value: ${{ jobs.config.outputs.stack-name }}
+
+
+jobs:
+ config:
+ runs-on: ubuntu-latest
+ outputs:
+ acceptance: ${{ steps.filter.outputs.acceptance }}
+ backend: ${{ steps.filter.outputs.backend }}
+ devops: ${{ steps.filter.outputs.devops }}
+ docs: ${{ steps.filter.outputs.docs }}
+ frontend: ${{ steps.filter.outputs.frontend }}
+ varnish: ${{ steps.filter.outputs.varnish }}
+ base-tag: ${{ steps.vars.outputs.base-tag }}
+ plone-version: ${{ steps.vars.outputs.plone-version }}
+ volto-version: ${{ steps.vars.outputs.volto-version }}
+ environment: ${{ steps.vars.outputs.environment }}
+ stack-name: ${{ steps.vars.outputs.stack-name }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Compute several vars needed for the CI
+ id: vars
+ shell: bash
+ run: |
+ echo "base-tag=sha-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
+ echo "plone-version=$(cat backend/version.txt)" >> $GITHUB_OUTPUT
+ python3 -c 'import json; data = json.load(open("./frontend/mrs.developer.json")); print("volto-version=" + (data["core"].get("tag") or "latest"))' >> $GITHUB_OUTPUT
+ ENVIRONMENT=${{ inputs.environment }}
+ echo "environment="${ENVIRONMENT} >> $GITHUB_OUTPUT
+ echo "stack-name=${ENVIRONMENT//./-}" >> $GITHUB_OUTPUT
+
+ - uses: dorny/paths-filter@v3.0.2
+ id: filter
+ with:
+ filters: |
+ acceptance:
+ - '.github/workflows/backend*'
+ - '.github/workflows/frontend*'
+ - 'backend/**'
+ - 'frontend/**'
+ backend:
+ - 'backend/**'
+ - '.github/workflows/backend*'
+ devops:
+ - 'devops/**'
+ docs:
+ - '.readthedocs.yaml'
+ - 'docs/**'
+ - '.github/workflows/docs.yaml'
+ frontend:
+ - 'frontend/**'
+ - '.github/workflows/frontend*'
+ varnish:
+ - "devops/varnish/**"
+ - ".github/workflows/varnish.yml"
+
+ - name: Test vars
+ run: |
+ echo "base-tag: ${{ steps.vars.outputs.base-tag }}"
+ echo 'plone-version: ${{ steps.vars.outputs.plone-version }}'
+ echo 'volto-version: ${{ steps.vars.outputs.volto-version }}'
+ echo 'event-name: ${{ github.event_name }}'
+ echo 'environment: ${{ steps.vars.outputs.environment }}'
+ echo 'stack-name: ${{ steps.vars.outputs.stack-name }}'
+ echo 'Paths - acceptance: ${{ steps.filter.outputs.acceptance }}'
+ echo 'Paths - backend: ${{ steps.filter.outputs.backend }}'
+ echo 'Paths - devops: ${{ steps.filter.outputs.devops }}'
+ echo 'Paths - docs: ${{ steps.filter.outputs.docs }}'
+ echo 'Paths - frontend: ${{ steps.filter.outputs.frontend }}'
+ echo 'Paths - varnish: ${{ steps.filter.outputs.frontend }}'
\ No newline at end of file
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 4460a23..8ffe738 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -1,147 +1,68 @@
name: Frontend CI
on:
- push:
- paths:
- - "frontend/**"
- - ".github/workflows/frontend.yml"
- workflow_dispatch:
-
-env:
- IMAGE_NAME_PREFIX: ghcr.io/pythonbrasil/pybr25-site
- IMAGE_NAME_SUFFIX: frontend
- NODE_VERSION: 20.x
-
-defaults:
- run:
- working-directory: ./frontend
+ workflow_call:
+ inputs:
+ base-tag:
+ required: true
+ type: string
+ image-name-prefix:
+ required: true
+ type: string
+ image-name-suffix:
+ required: true
+ type: string
+ node-version:
+ required: true
+ type: string
+ volto-version:
+ required: true
+ type: string
+ working-directory:
+ required: false
+ type: string
+ default: frontend
jobs:
- meta:
- runs-on: ubuntu-latest
- outputs:
- BASE_TAG: ${{ steps.vars.outputs.BASE_TAG }}
- VOLTO_VERSION: ${{ steps.vars.outputs.VOLTO_VERSION }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Compute several vars needed for the build
- id: vars
- run: |
- echo 'BASE_TAG=sha-$(git rev-parse --short HEAD)' >> $GITHUB_OUTPUT
- python3 -c 'import json; data = json.load(open("./mrs.developer.json")); print("VOLTO_VERSION=" + (data["core"].get("tag") or "latest"))' >> $GITHUB_OUTPUT
- - name: Test vars
- run: |
- echo 'BASE_TAG=${{ steps.vars.outputs.BASE_TAG }}'
- echo 'VOLTO_VERSION=${{ steps.vars.outputs.VOLTO_VERSION }}'
-
code-analysis:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout codebase
- uses: actions/checkout@v4
-
- - name: Use Node.js ${{ env.node-version }}
- uses: actions/setup-node@v4
- with:
- node-version: ${{ env.NODE_VERSION }}
-
- - name: Enable corepack
- run: |
- npm i -g corepack@latest
- corepack enable
-
- - name: Get pnpm store directory
- shell: bash
- run: |
- echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
-
- - uses: actions/cache@v4
- name: Setup pnpm cache
- with:
- path: ${{ env.STORE_PATH }}
- key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- restore-keys: |
- ${{ runner.os }}-pnpm-store-
-
- - name: Install dependencies
- run: make install
-
- - name: Linting
- id: lint
- if: ${{ success() || failure() }}
- run: make lint
-
- - name: i18n sync
- id: i18n
- if: ${{ success() || failure() }}
- run: make ci-i18n
-
- - name: Unit Tests
- id: unit
- if: ${{ success() || failure() }}
- run: make test
-
- - name: Report
- if: ${{ success() || failure() }}
- run: |
- echo '# Code Analysis' >> $GITHUB_STEP_SUMMARY
- echo '| Test | Status |' >> $GITHUB_STEP_SUMMARY
- echo '| --- | --- |' >> $GITHUB_STEP_SUMMARY
- echo '| Lint | ${{ steps.lint.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY
- echo '| i18n | ${{ steps.i18n.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY
- echo '| Unit Tests | ${{ steps.unit.conclusion == 'failure' && '❌' || ' ✅' }} |' >> $GITHUB_STEP_SUMMARY
+ name: "Frontend: Codeanalysis"
+ uses: plone/meta/.github/workflows/frontend-code.yml@2.x
+ with:
+ node-version: ${{ inputs.node-version }}
+ working-directory: ${{ inputs.working-directory }}
+
+ i18n:
+ name: "Frontend: i18n"
+ uses: plone/meta/.github/workflows/frontend-i18n.yml@2.x
+ with:
+ node-version: ${{ inputs.node-version }}
+ working-directory: ${{ inputs.working-directory }}
+
+ unit:
+ name: "Frontend: Unit tests"
+ uses: plone/meta/.github/workflows/frontend-unit.yml@2.x
+ with:
+ node-version: ${{ inputs.node-version }}
+ working-directory: ${{ inputs.working-directory }}
release:
- runs-on: ubuntu-latest
+ name: "Frontend: Build and publish container image"
+ uses: plone/meta/.github/workflows/container-image-build-push.yml@2.x
needs:
- - meta
- code-analysis
+ - i18n
+ - unit
permissions:
contents: read
packages: write
-
- steps:
-
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Docker meta
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: |
- ${{ env.IMAGE_NAME_PREFIX }}-${{ env.IMAGE_NAME_SUFFIX }}
- labels: |
- org.label-schema.docker.cmd=docker run -d -p 3000:3000 ${{ env.IMAGE_NAME_PREFIX }}-${{ env.IMAGE_NAME_SUFFIX }}:latest
- flavor:
- latest=false
- tags: |
- type=ref,event=branch
- type=sha
- type=raw,value=latest,enable={{is_default_branch}}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Login to Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Build and push
- uses: docker/build-push-action@v5
- with:
- platforms: linux/amd64
- context: frontend/
- file: frontend/Dockerfile
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- build-args: |
- VOLTO_VERSION=${{ needs.meta.outputs.VOLTO_VERSION }}
+ with:
+ base-tag: ${{ inputs.base-tag }}
+ image-name-prefix: ${{ inputs.image-name-prefix }}
+ image-name-suffix: ${{ inputs.image-name-suffix }}
+ working-directory: ${{ inputs.working-directory }}
+ build-args: |
+ VOLTO_VERSION=${{ inputs.volto-version }}
+ push: ${{ github.event_name != 'pull_request' }}
+ secrets:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..f547385
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,57 @@
+name: PythonBrasil 2025 CI
+
+on:
+ push:
+ paths:
+ - "backend/**"
+ - "frontend/**"
+ - ".github/workflows/*.yml"
+ - "devops/**"
+ workflow_dispatch:
+
+jobs:
+ config:
+ uses: ./.github/workflows/config.yml
+
+ backend:
+ uses: ./.github/workflows/backend.yml
+ needs:
+ - config
+ with:
+ base-tag: ${{ needs.config.outputs.base-tag }}
+ image-name-prefix: ${{ needs.config.outputs.image-name-prefix }}
+ image-name-suffix: backend
+ python-version: ${{ needs.config.outputs.python-version }}
+ plone-version: ${{ needs.config.outputs.plone-version }}
+ if: ${{ needs.config.outputs.backend == 'true' }}
+ permissions:
+ contents: read
+ packages: write
+
+ frontend:
+ uses: ./.github/workflows/frontend.yml
+ needs:
+ - config
+ with:
+ base-tag: ${{ needs.config.outputs.base-tag }}
+ image-name-prefix: ${{ needs.config.outputs.image-name-prefix }}
+ image-name-suffix: frontend
+ node-version: ${{ needs.config.outputs.node-version }}
+ volto-version: ${{ needs.config.outputs.volto-version }}
+ if: ${{ needs.config.outputs.frontend == 'true' }}
+ permissions:
+ contents: read
+ packages: write
+
+ varnish:
+ uses: ./.github/workflows/varnish.yml
+ needs:
+ - config
+ with:
+ base-tag: ${{ needs.config.outputs.base-tag }}
+ image-name-prefix: ${{ needs.config.outputs.image-name-prefix }}
+ image-name-suffix: varnish
+ if: ${{ needs.config.outputs.varnish == 'true' }}
+ permissions:
+ contents: read
+ packages: write
diff --git a/.github/workflows/manual_deploy.yml b/.github/workflows/manual_deploy.yml
deleted file mode 100644
index e040382..0000000
--- a/.github/workflows/manual_deploy.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-name: Manual Deployment of 2025.pythonbrasil.org.br
-
-on:
- workflow_dispatch:
-
-
-jobs:
-
- meta:
- runs-on: ubuntu-latest
- outputs:
- STACK_NAME: ${{ steps.vars.outputs.STACK_NAME }}
- ENVIRONMENT: ${{ steps.vars.outputs.ENVIRONMENT }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Set Env Vars
- id: vars
- run: |
- ENVIRONMENT=2025.pythonbrasil.org.br
- echo "ENVIRONMENT=${ENVIRONMENT}" >> $GITHUB_OUTPUT
- echo "STACK_NAME=${ENVIRONMENT//./-}" >> $GITHUB_OUTPUT
-
- deploy:
- if: ${{ github.ref == 'refs/heads/main' }}
- needs:
- - meta
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Deploy to cluster
- uses: kitconcept/docker-stack-deploy@v1.2.0
- with:
- registry: "ghcr.io"
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- remote_host: ${{ secrets.DEPLOY_HOST }}
- remote_port: ${{ secrets.DEPLOY_PORT }}
- remote_user: ${{ secrets.DEPLOY_USER }}
- remote_private_key: ${{ secrets.DEPLOY_SSH }}
- stack_file: devops/stacks/${{ needs.meta.outputs.ENVIRONMENT }}.yml
- stack_name: ${{ needs.meta.outputs.STACK_NAME }}
- stack_param: ${{ github.ref_name }}
- env_file: ${{ secrets.ENV_FILE }}
- deploy_timeout: 480
diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml
new file mode 100644
index 0000000..8f88ef3
--- /dev/null
+++ b/.github/workflows/tag.yml
@@ -0,0 +1,97 @@
+name: Deploy site
+
+on:
+ push:
+ tags:
+ - '20*'
+
+jobs:
+
+ config:
+ uses: ./.github/workflows/config.yml
+
+ backend-release:
+ name: "Backend: Build and publish Container Image"
+ uses: plone/meta/.github/workflows/container-image-build-push.yml@2.x
+ needs:
+ - config
+ permissions:
+ contents: read
+ packages: write
+ with:
+ base-tag: ${{ github.ref_name }}
+ image-name-prefix: ${{ needs.config.outputs.image-name-prefix }}
+ image-name-suffix: 'backend'
+ working-directory: 'backend'
+ build-args: |
+ PLONE_VERSION=${{ needs.config.outputs.plone-version }}
+ push: ${{ github.event_name != 'pull_request' }}
+ secrets:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ frontend-release:
+ name: "Frontend: Build and publish Container Image"
+ uses: plone/meta/.github/workflows/container-image-build-push.yml@2.x
+ needs:
+ - config
+ permissions:
+ contents: read
+ packages: write
+ with:
+ base-tag: ${{ github.ref_name }}
+ image-name-prefix: ${{ needs.config.outputs.image-name-prefix }}
+ image-name-suffix: 'frontend'
+ working-directory: 'frontend'
+ build-args: |
+ VOLTO_VERSION=${{ needs.config.outputs.volto-version }}
+ push: ${{ github.event_name != 'pull_request' }}
+ secrets:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ varnish-release:
+ name: "Varnish: Build and publish Container Image"
+ uses: plone/meta/.github/workflows/container-image-build-push.yml@2.x
+ needs:
+ - config
+ permissions:
+ contents: read
+ packages: write
+ with:
+ base-tag: ${{ github.ref_name }}
+ image-name-prefix: ${{ needs.config.outputs.image-name-prefix }}
+ image-name-suffix: 'varnish'
+ working-directory: 'devops/varnish'
+ build-args: ''
+ push: ${{ github.event_name != 'pull_request' }}
+ secrets:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ deploy:
+ needs:
+ - config
+ - backend-release
+ - frontend-release
+ - varnish-release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Deploy to cluster
+ uses: kitconcept/docker-stack-deploy@v1.2.0
+ with:
+ registry: "ghcr.io"
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ remote_host: ${{ secrets.DEPLOY_HOST }}
+ remote_port: ${{ secrets.DEPLOY_PORT }}
+ remote_user: ${{ secrets.DEPLOY_USER }}
+ remote_private_key: ${{ secrets.DEPLOY_SSH }}
+ stack_file: devops/stacks/${{ needs.config.outputs.environment }}.yml
+ stack_name: ${{ needs.config.outputs.stack-name }}
+ stack_param: ${{ github.ref_name }}
+ env_file: ${{ secrets.ENV_FILE }}
+ deploy_timeout: 480
\ No newline at end of file
diff --git a/.github/workflows/varnish.yml b/.github/workflows/varnish.yml
index 5af56d2..a839365 100644
--- a/.github/workflows/varnish.yml
+++ b/.github/workflows/varnish.yml
@@ -1,63 +1,38 @@
name: Varnish Image Creation
on:
- push:
- paths:
- - "devops/varnish/**"
- - ".github/workflows/varnish.yml"
- workflow_dispatch:
-
-env:
- IMAGE_NAME_PREFIX: ghcr.io/pythonbrasil/pybr25-site
- IMAGE_NAME_SUFFIX: varnish
+ workflow_call:
+ inputs:
+ base-tag:
+ required: true
+ type: string
+ image-name-prefix:
+ required: true
+ type: string
+ image-name-suffix:
+ required: false
+ type: string
+ default: varnish
+ working-directory:
+ required: false
+ type: string
+ default: backend
jobs:
release:
- runs-on: ubuntu-latest
+ name: "Varnish: Build and publish Container Image"
+ uses: plone/meta/.github/workflows/container-image-build-push.yml@2.x
permissions:
contents: read
packages: write
-
- steps:
-
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Docker meta
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: |
- ${{ env.IMAGE_NAME_PREFIX }}-${{ env.IMAGE_NAME_SUFFIX }}
- labels: |
- org.label-schema.docker.cmd=docker run -d -p 80:80 ${{ env.IMAGE_NAME_PREFIX }}-${{ env.IMAGE_NAME_SUFFIX }}:latest
- flavor:
- latest=false
- tags: |
- type=ref,event=branch
- type=sha
- type=raw,value=latest,enable={{is_default_branch}}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Login to Container Registry
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Build and push
- uses: docker/build-push-action@v4
- with:
- platforms: linux/amd64
- context: devops/varnish
- file: devops/varnish/Dockerfile
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
+ with:
+ base-tag: ${{ inputs.base-tag }}
+ image-name-prefix: ${{ inputs.image-name-prefix }}
+ image-name-suffix: ${{ inputs.image-name-suffix }}
+ working-directory: ${{ inputs.working-directory }}
+ build-args: ''
+ push: ${{ github.event_name != 'pull_request' }}
+ secrets:
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index d933aa8..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-repos:
- - repo: https://github.com/ddanier/sub-pre-commit.git
- rev: v3.7.1 # MUST match your pre-commit version
- hooks:
- - id: sub-pre-commit
- alias: backend
- name: "pre-commit for backend/"
- args: ["-p", "backend/"]
- files: "^backend/.*"
- stages: ["commit"]
- - id: sub-pre-commit
- alias: frontend
- name: "pre-commit for frontend"
- args: ["-p", "frontend"]
- files: "^frontend/.*"
- stages: ["commit"]
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..5fd9357
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ "recommendations": [
+ "charliermarsh.ruff",
+ "ms-python.python",
+ "redhat.vscode-yaml",
+ "editorconfig.editorconfig"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 1744666..44937d7 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,6 +2,14 @@
"eslint.workingDirectories": ["./frontend"],
"flake8.cwd": "${workspaceFolder}/backend",
"flake8.args": ["--config=pyproject.toml"],
- "black-formatter.cwd": "${workspaceFolder}/backend",
- "isort.args": ["--settings-path=${workspaceFolder}/backend/pyproject.toml"]
+ "ruff.organizeImports": true,
+ "python.terminal.activateEnvironment": true,
+ "python.testing.pytestArgs": [
+ "backend/tests"
+ ],
+ "python.testing.unittestEnabled": false,
+ "python.testing.pytestEnabled": true,
+ "[markdown]": {
+ "editor.formatOnSave": false
+ }
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d80904..8b94ec0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
-# Changes
+# Change log
-## 1.0.0 (2024-10-18)
+
-- Initial version [simplesconsultoria]
+
diff --git a/Makefile b/Makefile
index 6833ffe..bb83027 100644
--- a/Makefile
+++ b/Makefile
@@ -11,13 +11,13 @@ MAKEFLAGS+=--no-builtin-rules
CURRENT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
GIT_FOLDER=$(CURRENT_DIR)/.git
-PROJECT_NAME=2025.pythonbrasil.org.br
+PROJECT_NAME=pybr25-site
STACK_NAME=2025-pythonbrasil-org-br
+STACK_FILE=docker-compose-dev.yml
-VOLTO_VERSION = $(shell cat frontend/mrs.developer.json | python -c "import sys, json; print(json.load(sys.stdin)['core']['tag'])")
-PLONE_VERSION=$(shell cat backend/version.txt)
-PRE_COMMIT=pipx run --spec 'pre-commit==3.7.1' pre-commit
+VOLTO_VERSION=$(shell cat frontend/mrs.developer.json | python -c "import sys, json; print(json.load(sys.stdin)['core']['tag'])")
+PLONE_VERSION=$(shell cat backend/version.txt)
# We like colors
# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects
@@ -84,99 +84,121 @@ backend-test: ## Test backend codebase
@echo "Test backend"
$(MAKE) -C "./backend/" test
+###########################################
+# Environment
+###########################################
.PHONY: install
install: ## Install
@echo "Install Backend & Frontend"
- if [ -d $(GIT_FOLDER) ]; then $(PRE_COMMIT) install; else echo "$(RED) Not installing pre-commit$(RESET)";fi
$(MAKE) backend-install
$(MAKE) frontend-install
-.PHONY: start
-start: ## Start
- @echo "Starting application"
- $(MAKE) backend-start
- $(MAKE) frontend-start
-
.PHONY: clean
clean: ## Clean installation
@echo "Clean installation"
$(MAKE) -C "./backend/" clean
$(MAKE) -C "./frontend/" clean
+###########################################
+# QA
+###########################################
+.PHONY: format
+format: ## Format codebase
+ @echo "Format the codebase"
+ $(MAKE) -C "./backend/" format
+ $(MAKE) -C "./frontend/" format
+
+.PHONY: lint
+lint: ## Format codebase
+ @echo "Lint the codebasecodebase"
+ $(MAKE) -C "./backend/" lint
+ $(MAKE) -C "./frontend/" lint
+
.PHONY: check
-check: ## Lint and Format codebase
- @echo "Lint and Format codebase"
- $(PRE_COMMIT) run -a
+check: format lint ## Lint and Format codebase
+###########################################
+# i18n
+###########################################
.PHONY: i18n
i18n: ## Update locales
@echo "Update locales"
$(MAKE) -C "./backend/" i18n
$(MAKE) -C "./frontend/" i18n
+###########################################
+# Testing
+###########################################
.PHONY: test
test: backend-test frontend-test ## Test codebase
+###########################################
+# Container images
+###########################################
.PHONY: build-images
-build-images: ## Build docker images
+build-images: ## Build container images
@echo "Build"
$(MAKE) -C "./backend/" build-image
$(MAKE) -C "./frontend/" build-image
-## Docker stack
+###########################################
+# Local Stack
+###########################################
.PHONY: stack-start
stack-start: ## Local Stack: Start Services
@echo "Start local Docker stack"
- VOLTO_VERSION=$(VOLTO_VERSION) PLONE_VERSION=$(PLONE_VERSION) docker compose -f docker-compose.yml up -d --build
- @echo "Now visit: http://2025.pythonbrasil.org.br.localhost"
+ VOLTO_VERSION=$(VOLTO_VERSION) PLONE_VERSION=$(PLONE_VERSION) docker compose -f $(STACK_FILE) up -d --build
+ @echo "Now visit: http://pybr25-site.localhost"
-.PHONY: start-stack
+.PHONY: stack-create-site
stack-create-site: ## Local Stack: Create a new site
@echo "Create a new site in the local Docker stack"
- @docker compose -f docker-compose.yml exec backend ./docker-entrypoint.sh create-site
+ VOLTO_VERSION=$(VOLTO_VERSION) PLONE_VERSION=$(PLONE_VERSION) docker compose -f $(STACK_FILE) exec backend ./docker-entrypoint.sh create-site
-.PHONY: start-ps
+.PHONY: stack-status
stack-status: ## Local Stack: Check Status
@echo "Check the status of the local Docker stack"
- @docker compose -f docker-compose.yml ps
+ @docker compose -f $(STACK_FILE) ps
.PHONY: stack-stop
stack-stop: ## Local Stack: Stop Services
@echo "Stop local Docker stack"
- @docker compose -f docker-compose.yml stop
+ @docker compose -f $(STACK_FILE) stop
.PHONY: stack-rm
stack-rm: ## Local Stack: Remove Services and Volumes
@echo "Remove local Docker stack"
- @docker compose -f docker-compose.yml down
+ @docker compose -f $(STACK_FILE) down
@echo "Remove local volume data"
@docker volume rm $(PROJECT_NAME)_vol-site-data
-## Acceptance
+###########################################
+# Acceptance
+###########################################
.PHONY: acceptance-backend-dev-start
-acceptance-backend-dev-start: ## Build Acceptance Servers
- @echo "Build acceptance backend"
+acceptance-backend-dev-start:
+ @echo "Start acceptance backend"
$(MAKE) -C "./backend/" acceptance-backend-start
.PHONY: acceptance-frontend-dev-start
-acceptance-frontend-dev-start: ## Build Acceptance Servers
- @echo "Build acceptance backend"
+acceptance-frontend-dev-start:
+ @echo "Start acceptance frontend"
$(MAKE) -C "./frontend/" acceptance-frontend-dev-start
.PHONY: acceptance-test
-acceptance-test: ## Start Acceptance tests in interactive mode
- @echo "Build acceptance backend"
+acceptance-test:
+ @echo "Start acceptance tests in interactive mode"
$(MAKE) -C "./frontend/" acceptance-test
# Build Docker images
.PHONY: acceptance-frontend-image-build
-acceptance-frontend-image-build: ## Build Acceptance frontend server image
- @echo "Build acceptance frontend"
+acceptance-frontend-image-build:
+ @echo "Build acceptance frontend image"
@docker build frontend -t pythonbrasil/pybr25-site-frontend:acceptance -f frontend/Dockerfile --build-arg VOLTO_VERSION=$(VOLTO_VERSION)
.PHONY: acceptance-backend-image-build
-acceptance-backend-image-build: ## Build Acceptance backend server image
- @echo "Build acceptance backend"
+acceptance-backend-image-build:
+ @echo "Build acceptance backend image"
@docker build backend -t pythonbrasil/pybr25-site-backend:acceptance -f backend/Dockerfile.acceptance --build-arg PLONE_VERSION=$(PLONE_VERSION)
.PHONY: acceptance-images-build
@@ -185,14 +207,14 @@ acceptance-images-build: ## Build Acceptance frontend/backend images
$(MAKE) acceptance-frontend-image-build
.PHONY: acceptance-frontend-container-start
-acceptance-frontend-container-start: ## Start Acceptance frontend container
+acceptance-frontend-container-start:
@echo "Start acceptance frontend"
- @docker run --rm -p 3000:3000 --name 2025.pythonbrasil.org.br-frontend-acceptance --link 2025.pythonbrasil.org.br-backend-acceptance:backend -e RAZZLE_API_PATH=http://localhost:55001/plone -e RAZZLE_INTERNAL_API_PATH=http://backend:55001/plone -d pythonbrasil/pybr25-site-frontend:acceptance
+ @docker run --rm -p 3000:3000 --name pybr25-site-frontend-acceptance --link pybr25-site-backend-acceptance:backend -e RAZZLE_API_PATH=http://localhost:55001/plone -e RAZZLE_INTERNAL_API_PATH=http://backend:55001/plone -d pythonbrasil/pybr25-site-frontend:acceptance
.PHONY: acceptance-backend-container-start
-acceptance-backend-container-start: ## Start Acceptance backend container
+acceptance-backend-container-start:
@echo "Start acceptance backend"
- @docker run --rm -p 55001:55001 --name 2025.pythonbrasil.org.br-backend-acceptance -d pythonbrasil/pybr25-site-backend:acceptance
+ @docker run --rm -p 55001:55001 --name pybr25-site-backend-acceptance -d pythonbrasil/pybr25-site-backend:acceptance
.PHONY: acceptance-containers-start
acceptance-containers-start: ## Start Acceptance containers
@@ -202,11 +224,12 @@ acceptance-containers-start: ## Start Acceptance containers
.PHONY: acceptance-containers-stop
acceptance-containers-stop: ## Stop Acceptance containers
@echo "Stop acceptance containers"
- @docker stop 2025.pythonbrasil.org.br-frontend-acceptance
- @docker stop 2025.pythonbrasil.org.br-backend-acceptance
+ @docker stop pybr25-site-frontend-acceptance
+ @docker stop pybr25-site-backend-acceptance
.PHONY: ci-acceptance-test
-ci-acceptance-test: ## Run Acceptance tests in ci mode
+ci-acceptance-test:
+ @echo "Run acceptance tests in CI mode"
$(MAKE) acceptance-containers-start
pnpm dlx wait-on --httpTimeout 20000 http-get://localhost:55001/plone http://localhost:3000
$(MAKE) -C "./frontend/" ci-acceptance-test
diff --git a/README.md b/README.md
index e6cbff7..a2877ff 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
# PythonBrasil 2025 🚀
-[](https://github.com/plone/cookiecutter-plone/)
-[](https://github.com/ambv/black)
-[](https://github.com/pythonbrasil/pybr2025-site/actions/workflows/backend.yml)
-[](https://github.com/pythonbrasil/pybr2025-site/actions/workflows/frontend.yml)
+[](https://github.com/plone/cookieplone-templates/)
+[](https://github.com/psf/black)
+[](https://github.com/pythonbrasil/pybr25-site/actions/workflows/backend.yml)
+[](https://github.com/pythonbrasil/pybr25-site/actions/workflows/frontend.yml)
Encontro da comunidade Python Brasileira
@@ -11,47 +11,50 @@ Encontro da comunidade Python Brasileira
### Prerequisites ✅
-Ensure you have the following installed:
+- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned.
+- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv)
+- [nvm](https://6.docs.plone.org/install/create-project-cookieplone.html#nvm)
+- [Node.js and pnpm](https://6.docs.plone.org/install/create-project.html#node-js) 22
+- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make)
+- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git)
+- [Docker](https://docs.docker.com/get-started/get-docker/) (optional)
-- Python 3.11 🐍
-- Node 20 🟩
-- pnpm 🧶
-- Docker 🐳
### Installation 🔧
-1. Clone the repository:
+1. Clone this repository, then change your working directory.
-```shell
-git clone git@github.com:pythonbrasil/pybr2025-site.git
-cd 2025.pythonbrasil.org.br
-```
+ ```shell
+ git clone git@github.com:pythonbrasil/pybr25-site.git
+ cd pybr25-site
+ ```
-2. Install both Backend and Frontend:
+2. Install this code base.
+
+ ```shell
+ make install
+ ```
-```shell
-make install
-```
### Fire Up the Servers 🔥
-1. Create a new Plone site on your first run:
+1. Create a new Plone site on your first run.
-```shell
-make backend-create-site
-```
+ ```shell
+ make backend-create-site
+ ```
-2. Start the Backend at [http://localhost:8080/](http://localhost:8080/):
+2. Start the backend at http://localhost:8080/.
-```shell
-make backend-start
-```
+ ```shell
+ make backend-start
+ ```
-3. In a new terminal, start the Frontend at [http://localhost:3000/](http://localhost:3000/):
+3. In a new shell session, start the frontend at http://localhost:3000/.
-```shell
-make frontend-start
-```
+ ```shell
+ make frontend-start
+ ```
Voila! Your Plone site should be live and kicking! 🎉
@@ -61,7 +64,7 @@ Deploy a local `Docker Compose` environment that includes:
- Docker images for Backend and Frontend 🖼️
- A stack with a Traefik router and a Postgres database 🗃️
-- Accessible at [http://2025.pythonbrasil.org.br.localhost](http://2025.pythonbrasil.org.br.localhost) 🌐
+- Accessible at [http://pybr25-site.localhost](http://pybr25-site.localhost) 🌐
Execute the following:
@@ -74,11 +77,12 @@ And... you're all set! Your Plone site is up and running locally! 🚀
## Project Structure 🏗️
-This monorepo consists of three distinct sections: `backend`, `frontend`, and `devops`.
+This monorepo consists of the following distinct sections:
- **backend**: Houses the API and Plone installation, utilizing pip instead of buildout, and includes a policy package named pythonbrasil.site.
- **frontend**: Contains the React (Volto) package.
- **devops**: Encompasses Docker Stack, Ansible playbooks, and Cache settings.
+- **docs**: Scaffold for writing documentation for your project.
### Why This Structure? 🤔
@@ -95,6 +99,41 @@ To automatically format your code and ensure it adheres to quality standards, ex
make check
```
+### Format the codebase
+
+To format the codebase, it is possible to run `format`:
+
+```shell
+make format
+```
+
+| Section | Tool | Description | Configuration |
+| --- | --- | --- | --- |
+| backend | Ruff | Python code formatting, imports sorting | [`backend/pyproject.toml`](./backend/pyproject.toml) |
+| backend | `zpretty` | XML and ZCML formatting | -- |
+| frontend | ESLint | Fixes most common frontend issues | [`frontend/.eslintrc.js`](.frontend/.eslintrc.js) |
+| frontend | prettier | Format JS and Typescript code | [`frontend/.prettierrc`](.frontend/.prettierrc) |
+| frontend | Stylelint | Format Styles (css, less, sass) | [`frontend/.stylelintrc`](.frontend/.stylelintrc) |
+
+Formatters can also be run within the `backend` or `frontend` folders.
+
+### Linting the codebase
+or `lint`:
+
+ ```shell
+make lint
+```
+
+| Section | Tool | Description | Configuration |
+| --- | --- | --- | --- |
+| backend | Ruff | Checks code formatting, imports sorting | [`backend/pyproject.toml`](./backend/pyproject.toml) |
+| backend | Pyroma | Checks Python package metadata | -- |
+| backend | check-python-versions | Checks Python version information | -- |
+| backend | `zpretty` | Checks XML and ZCML formatting | -- |
+| frontend | ESLint | Checks JS / Typescript lint | [`frontend/.eslintrc.js`](.frontend/.eslintrc.js) |
+| frontend | prettier | Check JS / Typescript formatting | [`frontend/.prettierrc`](.frontend/.prettierrc) |
+| frontend | Stylelint | Check Styles (css, less, sass) formatting | [`frontend/.stylelintrc`](.frontend/.stylelintrc) |
+
Linters can be run individually within the `backend` or `frontend` folders.
## Internationalization 🌐
@@ -107,4 +146,4 @@ make i18n
## Credits and Acknowledgements 🙏
-Crafted with care by **Generated using [Cookieplone (0.7.1)](https://github.com/plone/cookieplone) and [cookiecutter-plone (f09571d)](https://github.com/plone/cookiecutter-plone/commit/f09571dbbf1117d5c3c9b48c6a6de514f3b575a6) on 2024-10-18 14:06:39.985935**. A special thanks to all contributors and supporters!
+Generated using [Cookieplone (0.9.7)](https://github.com/plone/cookieplone) and [cookieplone-templates (9d44151)](https://github.com/plone/cookieplone-templates/commit/9d441519e682ed62e67b8c8d1fe531d7368af5da) on 2025-04-24 16:14:26.309679. A special thanks to all contributors and supporters!
diff --git a/backend/.editorconfig b/backend/.editorconfig
index 8ae05aa..b3561a7 100644
--- a/backend/.editorconfig
+++ b/backend/.editorconfig
@@ -1,9 +1,6 @@
-# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
-# See the inline comments on how to expand/tweak this configuration file
-#
+
# EditorConfig Configuration file, for more details see:
-# http://EditorConfig.org
+# https://EditorConfig.org
# EditorConfig is a convention description, that could be interpreted
# by multiple editors to enforce common coding conventions for specific
# file types
@@ -22,33 +19,17 @@ trim_trailing_whitespace = true
charset = utf-8
# Indent style default
indent_style = space
-# Max Line Length - a hard line wrap, should be disabled
-max_line_length = off
[*.{py,cfg,ini}]
# 4 space indentation
indent_size = 4
-[*.{yml,zpt,pt,dtml,zcml}]
-# 2 space indentation
-indent_size = 2
-
-[*.{json,jsonl,js,jsx,ts,tsx,css,less,scss,html}] # Frontend development
+[*.{html,dtml,pt,zpt,xml,zcml,js,json,ts,less,scss,css,sass,yml,yaml}]
# 2 space indentation
indent_size = 2
-max_line_length = 80
[{Makefile,.gitmodules}]
# Tab indentation (no size specified, but view as 4 spaces)
indent_style = tab
indent_size = unset
tab_width = unset
-
-
-##
-# Add extra configuration options in .meta.toml:
-# [editorconfig]
-# extra_lines = """
-# _your own configuration lines_
-# """
-##
diff --git a/backend/.gitignore b/backend/.gitignore
index 6a1e51f..a39c756 100644
--- a/backend/.gitignore
+++ b/backend/.gitignore
@@ -1,51 +1,44 @@
-# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
-# See the inline comments on how to expand/tweak this configuration file
# python related
*.egg-info
*.pyc
*.pyo
# tools related
-build/
+__pycache__/
.coverage
+.mypy_cache
+.pytest_cache
+.ruff_cache
+/build/
coverage.xml
dist/
docs/_build
-__pycache__/
-.tox
-.vscode/
node_modules/
# venv / buildout related
+.eggs/
+.installed.cfg
+.mr.developer.cfg
+.venv/
bin/
develop-eggs/
eggs/
-.eggs/
etc/
-.installed.cfg
include/
lib/
lib64
-.mr.developer.cfg
parts/
pyvenv.cfg
var/
# mxdev
-/instance/
+.installed.txt
+.lock
/.make-sentinels/
/*-mxdev.txt
+/instance/
/reports/
/sources/
/venv/
-.installed.txt
-.lock
-
-##
-# Add extra configuration options in .meta.toml:
-# [gitignore]
-# extra_lines = """
-# _your own configuration lines_
-# """
-##
+constraints*.txt
+requirements*.txt
\ No newline at end of file
diff --git a/backend/.mrbob.ini b/backend/.mrbob.ini
new file mode 100644
index 0000000..23c6dac
--- /dev/null
+++ b/backend/.mrbob.ini
@@ -0,0 +1,4 @@
+[variables]
+package.dottedname = pythonbrasil.site
+package.browserlayer = IBrowserLayer
+
diff --git a/backend/.pre-commit-config.yaml b/backend/.pre-commit-config.yaml
deleted file mode 100644
index 47a8fad..0000000
--- a/backend/.pre-commit-config.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
-# See the inline comments on how to expand/tweak this configuration file
-ci:
- autofix_prs: false
- autoupdate_schedule: monthly
-
-repos:
-- repo: https://github.com/asottile/pyupgrade
- rev: v3.14.0
- hooks:
- - id: pyupgrade
- args: [--py38-plus]
-- repo: https://github.com/pycqa/isort
- rev: 5.12.0
- hooks:
- - id: isort
-- repo: https://github.com/psf/black
- rev: 23.9.1
- hooks:
- - id: black
-- repo: https://github.com/collective/zpretty
- rev: 3.1.0
- hooks:
- - id: zpretty
-
-##
-# Add extra configuration options in .meta.toml:
-# [pre_commit]
-# zpretty_extra_lines = """
-# _your own configuration lines_
-# """
-##
-- repo: https://github.com/PyCQA/flake8
- rev: 6.1.0
- hooks:
- - id: flake8
-
-##
-# Add extra configuration options in .meta.toml:
-# [pre_commit]
-# codespell_extra_lines = """
-# _your own configuration lines_
-# """
-##
-- repo: https://github.com/mgedmin/check-manifest
- rev: "0.49"
- hooks:
- - id: check-manifest
-- repo: https://github.com/regebro/pyroma
- rev: "4.2"
- hooks:
- - id: pyroma
-- repo: https://github.com/mgedmin/check-python-versions
- rev: "0.21.3"
- hooks:
- - id: check-python-versions
- args: ['--only', 'setup.py,pyproject.toml']
-- repo: https://github.com/collective/i18ndude
- rev: "6.1.0"
- hooks:
- - id: i18ndude
-
-
-##
-# Add extra configuration options in .meta.toml:
-# [pre_commit]
-# i18ndude_extra_lines = """
-# _your own configuration lines_
-# """
-##
-
-
-##
-# Add extra configuration options in .meta.toml:
-# [pre_commit]
-# extra_lines = """
-# _your own configuration lines_
-# """
-##
diff --git a/backend/CHANGES.md b/backend/CHANGELOG.md
similarity index 100%
rename from backend/CHANGES.md
rename to backend/CHANGELOG.md
diff --git a/backend/CONTRIBUTORS.md b/backend/CONTRIBUTORS.md
index 604867b..d57a273 100644
--- a/backend/CONTRIBUTORS.md
+++ b/backend/CONTRIBUTORS.md
@@ -1,3 +1,3 @@
# Contributors
-- PloneGov-BR [ericof@plone.org]
+- PloneGov-BR [gov@plone.org.br]
diff --git a/backend/Dockerfile b/backend/Dockerfile
index 2de9618..01ed176 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -1,41 +1,127 @@
-# syntax=docker/dockerfile:1
-ARG PLONE_VERSION=6.1.0
-FROM plone/server-builder:${PLONE_VERSION} as builder
+# syntax=docker/dockerfile:1.9
+FROM ubuntu:noble AS builder
-WORKDIR /app
+ARG PYTHON_VERSION=3.12
+ARG PB_VERSION
+
+SHELL ["sh", "-exc"]
+ENV DEBIAN_FRONTEND=noninteractive
+RUN <.
+STOPSIGNAL SIGINT
+
+# Expose /data as a volume
+VOLUME /data
+
+# Expose Zope Port
+EXPOSE 8080
+
+# Use /app as the workdir
+WORKDIR /app
+
+# Set healthcheck to port 8080
+HEALTHCHECK --interval=10s --timeout=5s --start-period=60s CMD [ -n "$LISTEN_PORT" ] || LISTEN_PORT=8080 ; wget -q http://127.0.0.1:"$LISTEN_PORT"/ok -O - | grep OK || exit 1
+
# Copy /app from builder
-COPY --from=builder /app /app
+COPY --from=builder --chown=500:500 /app /app
RUN <= tuple(map(int, '$(PYTHON_VERSION_MIN)'.split('.'))))")
-ifeq ($(PYTHON_VERSION_OK),0)
- $(error "Need python $(PYTHON_VERSION) >= $(PYTHON_VERSION_MIN)")
+ifeq (, $(shell which $(UV) ))
+ $(error "UV=$(UV) not found in $(PATH)")
endif
PLONE_SITE_ID=Plone
@@ -38,10 +31,12 @@ BACKEND_FOLDER=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
PLONE_VERSION=$(shell cat $(BACKEND_FOLDER)/version.txt)
EXAMPLE_CONTENT_FOLDER=${BACKEND_FOLDER}/src/pythonbrasil/site/setuphandlers/examplecontent
-GIT_FOLDER=$(BACKEND_FOLDER)/.git
VENV_FOLDER=$(BACKEND_FOLDER)/.venv
BIN_FOLDER=$(VENV_FOLDER)/bin
+# Environment variables to be exported
+export PYTHONWARNINGS := ignore
+export DOCKER_BUILDKIT := 1
all: build
@@ -51,89 +46,99 @@ all: build
help: ## This help message
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
-$(BIN_FOLDER)/pip $(BIN_FOLDER)/tox $(BIN_FOLDER)/pipx $(BIN_FOLDER)/uv $(BIN_FOLDER)/mxdev:
- @echo "$(GREEN)==> Setup Virtual Env$(RESET)"
- $(PYTHON) -m venv $(VENV_FOLDER)
- $(BIN_FOLDER)/pip install -U "pip" "uv" "wheel" "pipx" "mxdev" "tox" "pre-commit"
- if [ -d $(GIT_FOLDER) ]; then $(BIN_FOLDER)/pre-commit install; else echo "$(RED) Not installing pre-commit$(RESET)";fi
+$(VENV_FOLDER): ## Install dependencies
+ @echo "$(GREEN)==> Install environment$(RESET)"
+ @uv sync
+
+.PHONY: sync
+sync: $(VENV_FOLDER) ## Sync project dependencies
+ @echo "$(GREEN)==> Sync project dependencies$(RESET)"
+ @uv sync
-instance/etc/zope.ini: $(BIN_FOLDER)/pip ## Create instance configuration
+instance/etc/zope.ini instance/etc/zope.conf: instance.yaml ## Create instance configuration
@echo "$(GREEN)==> Create instance configuration$(RESET)"
- $(BIN_FOLDER)/pipx run cookiecutter -f --no-input --config-file instance.yaml gh:plone/cookiecutter-zope-instance
+ @uvx cookiecutter -f --no-input -c 2.1.1 --config-file instance.yaml gh:plone/cookiecutter-zope-instance
.PHONY: config
config: instance/etc/zope.ini
-.PHONY: build-dev
-build-dev: config ## Install Plone packages
- @echo "$(GREEN)==> Setup Build$(RESET)"
- $(BIN_FOLDER)/mxdev -c mx.ini
- $(BIN_FOLDER)/uv pip install -r requirements-mxdev.txt
-
.PHONY: install
-install: build-dev ## Install Plone
-
-.PHONY: build
-build: build-dev ## Install Plone
+install: $(VENV_FOLDER) config ## Install Plone and dependencies
.PHONY: clean
-clean: ## Clean environment
+clean: ## Clean installation and instance
@echo "$(RED)==> Cleaning environment and build$(RESET)"
- rm -rf $(VENV_FOLDER) pyvenv.cfg .installed.cfg instance .tox .venv .pytest_cache
+ @rm -rf $(VENV_FOLDER) pyvenv.cfg .installed.cfg instance/etc .venv .pytest_cache .ruff_cache constraints* requirements*
+
+.PHONY: remove-data
+remove-data: ## Remove all content
+ @echo "$(RED)==> Removing all content$(RESET)"
+ rm -rf $(VENV_FOLDER) instance/var
.PHONY: start
-start: ## Start a Plone instance on localhost:8080
- PYTHONWARNINGS=ignore $(BIN_FOLDER)/runwsgi instance/etc/zope.ini
+start: $(VENV_FOLDER) instance/etc/zope.ini ## Start a Plone instance on localhost:8080
+ @uv run runwsgi instance/etc/zope.ini
.PHONY: console
-console: instance/etc/zope.ini ## Start a console into a Plone instance
- PYTHONWARNINGS=ignore $(BIN_FOLDER)/zconsole debug instance/etc/zope.conf
+console: $(VENV_FOLDER) instance/etc/zope.ini ## Start a console into a Plone instance
+ @uv run zconsole debug instance/etc/zope.conf
.PHONY: create-site
-create-site: instance/etc/zope.ini ## Create a new site from scratch
- PYTHONWARNINGS=ignore $(BIN_FOLDER)/zconsole run instance/etc/zope.conf ./scripts/create_site.py
+create-site: $(VENV_FOLDER) instance/etc/zope.ini ## Create a new site from scratch
+ @uv run zconsole run instance/etc/zope.conf ./scripts/create_site.py
# Example Content
.PHONY: update-example-content
-update-example-content: $(BIN_FOLDER)/tox ## Export example content inside package
+update-example-content: $(VENV_FOLDER) ## Export example content inside package
@echo "$(GREEN)==> Export example content into $(EXAMPLE_CONTENT_FOLDER) $(RESET)"
if [ -d $(EXAMPLE_CONTENT_FOLDER)/content ]; then rm -r $(EXAMPLE_CONTENT_FOLDER)/* ;fi
- $(BIN_FOLDER)/plone-exporter instance/etc/zope.conf $(PLONE_SITE_ID) $(EXAMPLE_CONTENT_FOLDER)
-
-.PHONY: check
-check: $(BIN_FOLDER)/tox ## Check and fix code base according to Plone standards
+ @uv run plone-exporter instance/etc/zope.conf $(PLONE_SITE_ID) $(EXAMPLE_CONTENT_FOLDER)
+
+# QA
+.PHONY: lint
+lint: ## Check and fix code base according to Plone standards
+ @echo "$(GREEN)==> Lint codebase$(RESET)"
+ @uvx ruff@latest check --fix --config $(BACKEND_FOLDER)/pyproject.toml
+ @uvx pyroma@latest -d .
+ @uvx check-python-versions@latest .
+ @uvx zpretty@latest --check src
+
+.PHONY: format
+format: ## Check and fix code base according to Plone standards
@echo "$(GREEN)==> Format codebase$(RESET)"
- $(BIN_FOLDER)/tox -e lint
+ @uvx ruff@latest check --select I --fix --config $(BACKEND_FOLDER)/pyproject.toml
+ @uvx ruff@latest format --config $(BACKEND_FOLDER)/pyproject.toml
+ @uvx zpretty@latest -i src
# i18n
-$(BIN_FOLDER)/i18ndude: $(BIN_FOLDER)/pip
- @echo "$(GREEN)==> Install translation tools$(RESET)"
- $(BIN_FOLDER)/uv pip install i18ndude
-
.PHONY: i18n
-i18n: $(BIN_FOLDER)/i18ndude ## Update locales
+i18n: $(VENV_FOLDER) ## Update locales
@echo "$(GREEN)==> Updating locales$(RESET)"
- $(BIN_FOLDER)/update_locale
+ @uv run python -m pythonbrasil.site.locales
# Tests
.PHONY: test
-test: $(BIN_FOLDER)/tox ## run tests
- $(BIN_FOLDER)/tox -e test
+test: $(VENV_FOLDER) ## run tests
+ @uv run pytest
.PHONY: test-coverage
-test-coverage: $(BIN_FOLDER)/tox ## run tests with coverage
- $(BIN_FOLDER)/tox -e coverage
+test-coverage: $(VENV_FOLDER) ## run tests with coverage
+ @uv run pytest --cov=pythonbrasil.site --cov-report term-missing
# Build Docker images
.PHONY: build-image
build-image: ## Build Docker Images
- @DOCKER_BUILDKIT=1 docker build . -t $(IMAGE_NAME_PREFIX)-backend:$(IMAGE_TAG) -f Dockerfile --build-arg PLONE_VERSION=$(PLONE_VERSION)
+ @docker build . -t $(IMAGE_NAME_PREFIX)-backend:$(IMAGE_TAG) -f Dockerfile --build-arg PLONE_VERSION=$(PLONE_VERSION)
# Acceptance tests
.PHONY: acceptance-backend-start
acceptance-backend-start: ## Start backend acceptance server
- ZSERVER_HOST=0.0.0.0 ZSERVER_PORT=55001 LISTEN_PORT=55001 APPLY_PROFILES="pythonbrasil/site:default" CONFIGURE_PACKAGES="plone.restapi,plone.volto,plone.volto.cors,pythonbrasil/site" $(BIN_FOLDER)/robot-server plone.app.robotframework.testing.VOLTO_ROBOT_TESTING
+ ZSERVER_HOST=0.0.0.0 ZSERVER_PORT=55001 LISTEN_PORT=55001 APPLY_PROFILES="pythonbrasil.site:default" CONFIGURE_PACKAGES="plone.restapi,plone.volto,plone.volto.cors,pythonbrasil.site" $(BIN_FOLDER)/robot-server plone.app.robotframework.testing.VOLTO_ROBOT_TESTING
.PHONY: acceptance-image-build
acceptance-image-build: ## Build Docker Images
- @DOCKER_BUILDKIT=1 docker build . -t $(IMAGE_NAME_PREFIX)-backend-acceptance:$(IMAGE_TAG) -f Dockerfile.acceptance --build-arg PLONE_VERSION=$(PLONE_VERSION)
+ @docker build . -t $(IMAGE_NAME_PREFIX)-backend-acceptance:$(IMAGE_TAG) -f Dockerfile.acceptance --build-arg PLONE_VERSION=$(PLONE_VERSION)
+
+## Add bobtemplates features (check bobtemplates.plone's documentation to get the list of available features)
+add: $(VENV_FOLDER)
+ @uvx plonecli add -b .mrbob.ini $(filter-out $@,$(MAKECMDGOALS))
diff --git a/backend/README.md b/backend/README.md
index 9e331e6..71cb772 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -8,26 +8,80 @@ TODO: List our awesome features
## Installation
-Install pythonbrasil.site with `pip`:
+Install pythonbrasil.site with uv.
```shell
-pip install pythonbrasil.site
+uv add pythonbrasil.site
```
-And to create the Plone site:
+
+Create the Plone site.
```shell
-make create_site
+make create-site
```
## Contribute
-- [Issue Tracker](https://github.com/simplesconsultoria/pythonbrasil.site/issues)
-- [Source Code](https://github.com/simplesconsultoria/pythonbrasil.site/)
+- [Issue tracker](https://github.com/pythonbrasil/pybr25-site/issues)
+- [Source code](https://github.com/pythonbrasil/pybr25-site/)
+
+### Prerequisites ✅
+
+- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned.
+- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv)
+- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make)
+- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git)
+- [Docker](https://docs.docker.com/get-started/get-docker/) (optional)
+
+### Installation 🔧
+
+1. Clone this repository.
+
+ ```shell
+ git clone git@github.com:pythonbrasil/pybr25-site.git
+ cd pybr25-site/backend
+ ```
+
+2. Install this code base.
+
+ ```shell
+ make install
+ ```
+
+
+### Add features using `plonecli` or `bobtemplates.plone`
+
+This package provides markers as strings (``) that are compatible with [`plonecli`](https://github.com/plone/plonecli) and [`bobtemplates.plone`](https://github.com/plone/bobtemplates.plone).
+These markers act as hooks to add all kinds of features through subtemplates, including behaviors, control panels, upgrade steps, or other subtemplates from `bobtemplates.plone`.
+`plonecli` is a command line client for `bobtemplates.plone`, adding autocompletion and other features.
+
+To add a feature as a subtemplate to your package, use the following command pattern.
+
+```shell
+make add
+```
+
+For example, you can add a content type to your package with the following command.
+
+```shell
+make add content_type
+```
+
+You can add a behavior with the following command.
+
+```shell
+make add behavior
+```
+
+```{seealso}
+You can check the list of available subtemplates in the [`bobtemplates.plone` `README.md` file](https://github.com/plone/bobtemplates.plone/?tab=readme-ov-file#provided-subtemplates).
+See also the documentation of [Mockup and Patternslib](https://6.docs.plone.org/classic-ui/mockup.html) for how to build the UI toolkit for Classic UI.
+```
## License
The project is licensed under GPLv2.
-## Credits and Acknowledgements 🙏
+## Credits and acknowledgements 🙏
-Crafted with care by **This was generated by [cookiecutter-plone](https://github.com/plone/cookieplone-templates/backend_addon) on 2024-10-18 17:08:49**. A special thanks to all contributors and supporters!
+Generated from the [`cookieplone-templates` template](https://github.com/plone/cookieplone-templates/tree/main/) on 2025-04-24 19:16:45.. A special thanks to all contributors and supporters!
diff --git a/backend/bobtemplate.cfg b/backend/bobtemplate.cfg
new file mode 100644
index 0000000..39fc98c
--- /dev/null
+++ b/backend/bobtemplate.cfg
@@ -0,0 +1,5 @@
+[main]
+version = 6.0.13
+template = plone_addon
+git_init = True
+python = python3
diff --git a/backend/constraints.txt b/backend/constraints.txt
deleted file mode 100644
index e33087a..0000000
--- a/backend/constraints.txt
+++ /dev/null
@@ -1 +0,0 @@
--c https://dist.plone.org/release/6.1.0/constraints.txt
diff --git a/backend/container/compile_mo.py b/backend/container/compile_mo.py
new file mode 100755
index 0000000..2857772
--- /dev/null
+++ b/backend/container/compile_mo.py
@@ -0,0 +1,66 @@
+"""Helper script to pre-compile PO files in a Plone backend builder image."""
+
+from collections.abc import Generator
+from pathlib import Path
+from pythongettext.msgfmt import Msgfmt
+from pythongettext.msgfmt import PoSyntaxError
+
+import logging
+import os
+
+
+# Allow you to change the base folder of the application
+APP_FOLDER: str = os.environ.get("APP_FOLDER", "/app")
+LOG_FOLDER: str = "/var/log"
+
+
+logging.basicConfig(filename=Path(f"{LOG_FOLDER}/compile_mo.log"))
+logger = logging.getLogger("compile-mo")
+logger.setLevel(logging.DEBUG)
+
+
+def compile_po_file(po_file: Path) -> Path | None:
+ """Compile a single PO file."""
+ # Search for a .mo file in the same directory
+ parent: Path = po_file.parent
+ domain: str = po_file.name[: -len(po_file.suffix)]
+ mo_file: Path = parent / f"{domain}.mo"
+ do_compile: bool = True
+
+ if mo_file.exists():
+ # Check if an existing file needs to be recompiled
+ do_compile = os.stat(mo_file).st_mtime < os.stat(po_file).st_mtime
+
+ if do_compile:
+ try:
+ mo = Msgfmt(f"{po_file}", name=domain).getAsFile()
+ except PoSyntaxError:
+ logger.error(f" -- Error while compiling language file {mo_file}")
+ return
+ else:
+ with open(mo_file, "wb") as f_out:
+ try:
+ f_out.write(mo.read())
+ except OSError:
+ logger.error(f" -- Error writing language file {mo_file}")
+ return
+ logger.info(f" -- Compiled language file {mo_file}")
+ else:
+ logger.info(f" -- Already coimpiled language file {mo_file}")
+ return mo_file
+
+
+def main():
+ lib_path: Path = Path(f"{APP_FOLDER}/lib").resolve()
+ po_files: Generator = lib_path.glob("**/*.po")
+ mo_files: list = []
+ logger.info("Starting compilation of po files")
+ for po_file in po_files:
+ mo_file = compile_po_file(po_file)
+ if mo_file:
+ mo_files.append(mo_file)
+ logger.info(f"Compiled {len(mo_files)} files")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/backend/container/skeleton/docker-entrypoint.sh b/backend/container/skeleton/docker-entrypoint.sh
new file mode 100755
index 0000000..a993a08
--- /dev/null
+++ b/backend/container/skeleton/docker-entrypoint.sh
@@ -0,0 +1,179 @@
+#!/bin/bash
+set -e
+export VENVBIN=/app/bin
+
+if [ -z "${PIP_PARAMS}" ]; then
+ PIP_PARAMS=""
+fi
+
+if [ -z "${CLIENT_HOME}" ]; then
+ CLIENT_HOME="/data/$(hostname)/$(hostid)"
+ export CLIENT_HOME=$CLIENT_HOME
+fi
+
+USER="$(id -u)"
+
+# Create directories to be used by Plone
+mkdir -p /data/filestorage /data/blobstorage /data/cache /data/log $CLIENT_HOME
+if [ "$USER" = '0' ]; then
+ find /data -not -user plone -exec chown plone:plone {} \+
+ sudo="gosu plone"
+else
+ sudo=""
+fi
+
+# MAIN ENV Vars
+[ -z ${SECURITY_POLICY_IMPLEMENTATION+x} ] && export SECURITY_POLICY_IMPLEMENTATION=C
+[ -z ${VERBOSE_SECURITY+x} ] && export VERBOSE_SECURITY=off
+[ -z ${DEFAULT_ZPUBLISHER_ENCODING+x} ] && export DEFAULT_ZPUBLISHER_ENCODING=utf-8
+[ -z ${COMPILE_MO_FILES+x} ] && export COMPILE_MO_FILES=true
+[ -z ${DEBUG_MODE+x} ] && export DEBUG_MODE=off
+[ -z ${ZOPE_FORM_MEMORY_LIMIT+x} ] && export ZOPE_FORM_MEMORY_LIMIT=4MB
+[ -z ${ZOPE_FORM_DISK_LIMIT+x} ] && export ZOPE_FORM_DISK_LIMIT=1GB
+[ -z ${ZOPE_FORM_MEMFILE_LIMIT+x} ] && export ZOPE_FORM_MEMFILE_LIMIT=4KB
+
+
+# ZODB ENV Vars
+[ -z ${ZODB_CACHE_SIZE+x} ] && export ZODB_CACHE_SIZE=50000
+
+if [[ -v RELSTORAGE_DSN ]]; then
+ MSG="Using Relstorage configuration"
+ CONF=relstorage.conf
+ # Relstorage ENV Vars
+ [ -z ${RELSTORAGE_NAME+x} ] && export RELSTORAGE_NAME=storage
+ [ -z ${RELSTORAGE_READ_ONLY+x} ] && export RELSTORAGE_READ_ONLY=off
+ [ -z ${RELSTORAGE_KEEP_HISTORY+x} ] && export RELSTORAGE_KEEP_HISTORY=true
+ [ -z ${RELSTORAGE_COMMIT_LOCK_TIMEOUT+x} ] && export RELSTORAGE_COMMIT_LOCK_TIMEOUT=30
+ [ -z ${RELSTORAGE_CREATE_SCHEMA+x} ] && export RELSTORAGE_CREATE_SCHEMA=true
+ [ -z ${RELSTORAGE_SHARED_BLOB_DIR+x} ] && export RELSTORAGE_SHARED_BLOB_DIR=false
+ [ -z ${RELSTORAGE_BLOB_CACHE_SIZE+x} ] && export RELSTORAGE_BLOB_CACHE_SIZE=100mb
+ [ -z ${RELSTORAGE_BLOB_CACHE_SIZE_CHECK+x} ] && export RELSTORAGE_BLOB_CACHE_SIZE_CHECK=10
+ [ -z ${RELSTORAGE_BLOB_CACHE_SIZE_CHECK_EXTERNAL+x} ] && export RELSTORAGE_BLOB_CACHE_SIZE_CHECK_EXTERNAL=false
+ [ -z ${RELSTORAGE_BLOB_CHUNK_SIZE+x} ] && export RELSTORAGE_BLOB_CHUNK_SIZE=1048576
+ [ -z ${RELSTORAGE_CACHE_LOCAL_MB+x} ] && export RELSTORAGE_CACHE_LOCAL_MB=10
+ [ -z ${RELSTORAGE_CACHE_LOCAL_OBJECT_MAX+x} ] && export RELSTORAGE_CACHE_LOCAL_OBJECT_MAX=16384
+ [ -z ${RELSTORAGE_CACHE_LOCAL_COMPRESSION+x} ] && export RELSTORAGE_CACHE_LOCAL_COMPRESSION=none
+ [ -z ${RELSTORAGE_CACHE_DELTA_SIZE_LIMIT+x} ] && export RELSTORAGE_CACHE_DELTA_SIZE_LIMIT=100000
+elif [[ -v ZEO_ADDRESS ]]; then
+ MSG="Using ZEO configuration"
+ CONF=zeo.conf
+ # Check ZEO variables
+ [ -z ${ZEO_SHARED_BLOB_DIR+x} ] && export ZEO_SHARED_BLOB_DIR=off
+ [ -z ${ZEO_READ_ONLY+x} ] && export ZEO_READ_ONLY=false
+ [ -z ${ZEO_CLIENT_READ_ONLY_FALLBACK+x} ] && export ZEO_CLIENT_READ_ONLY_FALLBACK=false
+ [ -z ${ZEO_STORAGE+x} ] && export ZEO_STORAGE=1
+ [ -z ${ZEO_CLIENT_CACHE_SIZE+x} ] && export ZEO_CLIENT_CACHE_SIZE=128MB
+ [ -z ${ZEO_DROP_CACHE_RATHER_VERIFY+x} ] && export ZEO_DROP_CACHE_RATHER_VERIFY=false
+else
+ MSG="Using default configuration"
+ CONF=zope.conf
+fi
+
+# Add anything inside etc/zope.conf.d to the configuration file
+# prior to starting the respective Zope server.
+# This provides a counterpart for the ZCML package-includes
+# functionality, but for Zope configuration snippets.
+#
+# This must be executed only once during the container lifetime,
+# as container can be stopped and then restarted... double-additions
+# of the same snippet cause the Zope server not to start.
+if grep -q '# Runtime customizations:' etc/${CONF} ; then
+ # Note in the log this was customized. Useful for bug reports.
+ MSG="${MSG} -- with customizations"
+else
+ # Assume there will be no customizations.
+ zope_conf_vanilla=true
+ for f in etc/zope.conf.d/*.conf ; do
+ test -f ${f} || continue
+ # Oh, it looks like there is at least one customization.
+ if [[ -v zope_conf_vanilla ]] ; then
+ # Make a note both in the file and in the log.
+ echo >> etc/${CONF}
+ echo "# Runtime customizations:" >> etc/${CONF}
+ MSG="${MSG} -- with customizations"
+ # We don't need to rerun the same snippet twice here.
+ unset zope_conf_vanilla
+ fi
+ echo >> etc/${CONF}
+ cat ${f} >> etc/${CONF}
+ done
+fi
+
+# Handle CORS
+$sudo $VENVBIN/python /app/scripts/cors.py
+
+# Handle ADDONS installation
+if [[ -n "${ADDONS}" ]]; then
+ echo "======================================================================================="
+ echo "Installing ADDONS ${ADDONS}"
+ echo "THIS IS NOT MEANT TO BE USED IN PRODUCTION"
+ echo "Read about it: https://6.docs.plone.org/install/containers/images/backend.html"
+ echo "======================================================================================="
+ $VENVBIN/pip install ${ADDONS} ${PIP_PARAMS}
+fi
+
+# Handle development addons
+if [[ -v DEVELOP ]]; then
+ echo "======================================================================================="
+ echo "Installing DEVELOPment addons ${DEVELOP}"
+ echo "THIS IS NOT MEANT TO BE USED IN PRODUCTION"
+ echo "Read about it: https://6.docs.plone.org/install/containers/images/backend.html"
+ echo "======================================================================================="
+ PACKAGES=""
+ while read -ra DEVADDONS; do
+ for a in "${DEVADDONS[@]}"; do
+ PACKAGES+=" --editable ${a}"
+ done
+ done <<< "$DEVELOP"
+ $VENVBIN/pip install ${PACKAGES} ${PIP_PARAMS}
+fi
+
+if [[ "$1" == "start" ]]; then
+ # Handle Site creation
+ if [[ -v SITE ]]; then
+ export TYPE=${TYPE:-volto}
+ echo "======================================================================================="
+ echo "Creating Plone ${TYPE} SITE: ${SITE}"
+ echo "Aditional profiles: ${PROFILES}"
+ echo "THIS IS NOT MEANT TO BE USED IN PRODUCTION"
+ echo "Read about it: https://6.docs.plone.org/install/containers/images/backend.html"
+ echo "======================================================================================="
+ export SITE_ID=${SITE}
+ $sudo $VENVBIN/zconsole run etc/${CONF} /app/scripts/create_site.py
+ fi
+ echo $MSG
+ if [[ -v LISTEN_PORT ]] ; then
+ # Ensure the listen port can be set via container --environment.
+ # Necessary to run multiple backends in a single Podman / Kubernetes pod.
+ sed -i "s/port = 8080/port = ${LISTEN_PORT}/" etc/zope.ini
+ fi
+ exec $sudo $VENVBIN/runwsgi -v etc/zope.ini config_file=${CONF}
+elif [[ "$1" == "create-classic" ]]; then
+ export TYPE=classic
+ exec $sudo $VENVBIN/zconsole run etc/${CONF} /app/scripts/create_site.py
+elif [[ "$1" == "create-volto" ]]; then
+ export TYPE=volto
+ exec $sudo $VENVBIN/zconsole run etc/${CONF} /app/scripts/create_site.py
+elif [[ "$1" == "create-site" ]]; then
+ export TYPE=${TYPE:-volto}
+ exec $sudo $VENVBIN/zconsole run etc/${CONF} /app/scripts/create_site.py
+elif [[ "$1" == "console" ]]; then
+ exec $sudo $VENVBIN/zconsole debug etc/${CONF}
+elif [[ "$1" == "run" ]]; then
+ exec $sudo $VENVBIN/zconsole run etc/${CONF} "${@:2}"
+elif [[ "$1" == "addzopeuser" ]]; then
+ exec $sudo $VENVBIN/addzopeuser -c etc/${CONF} "${@:2}"
+elif [[ "$1" == "export" ]]; then
+ exec $sudo $VENVBIN/plone-exporter etc/${CONF} "${@:2}" "${@:3}"
+elif [[ "$1" == "pack" ]]; then
+ if [[ -v ZEO_ADDRESS ]]; then
+ exec $sudo $VENVBIN/zeopack "${@:2}" ${ZEO_ADDRESS}
+ elif [[ -v RELSTORAGE_DSN ]]; then
+ exec $sudo $VENVBIN/zodbpack "${@:2}" etc/relstorage_pack.conf
+ else
+ exec $sudo $VENVBIN/zconsole run etc/${CONF} /app/scripts/pack.py
+ fi
+else
+ # Custom
+ exec "$@"
+fi
diff --git a/backend/docs/.gitkeep b/backend/container/skeleton/etc/package-includes/.gitkeep
similarity index 100%
rename from backend/docs/.gitkeep
rename to backend/container/skeleton/etc/package-includes/.gitkeep
diff --git a/backend/container/skeleton/etc/relstorage.conf b/backend/container/skeleton/etc/relstorage.conf
new file mode 100644
index 0000000..93a44d6
--- /dev/null
+++ b/backend/container/skeleton/etc/relstorage.conf
@@ -0,0 +1,41 @@
+%define INSTANCE /app
+instancehome $INSTANCE
+
+%define CLIENTHOME $(CLIENT_HOME)
+clienthome $CLIENTHOME
+
+debug-mode $(DEBUG_MODE)
+security-policy-implementation $(SECURITY_POLICY_IMPLEMENTATION)
+verbose-security $(VERBOSE_SECURITY)
+default-zpublisher-encoding $(DEFAULT_ZPUBLISHER_ENCODING)
+
+
+ CHAMELEON_CACHE $INSTANCE/var/cache
+
+
+
+ form-memory-limit $(ZOPE_FORM_MEMORY_LIMIT)
+
+
+
+ # Main database
+ cache-size $(ZODB_CACHE_SIZE)
+ %import relstorage
+
+ name $(RELSTORAGE_NAME)
+ read-only $(RELSTORAGE_READ_ONLY)
+ keep-history $(RELSTORAGE_KEEP_HISTORY)
+ commit-lock-timeout $(RELSTORAGE_COMMIT_LOCK_TIMEOUT)
+ create-schema $(RELSTORAGE_CREATE_SCHEMA)
+ blob-dir $INSTANCE/var/blobstorage
+ shared-blob-dir $(RELSTORAGE_SHARED_BLOB_DIR)
+ blob-cache-size $(RELSTORAGE_BLOB_CACHE_SIZE)
+ blob-cache-size-check $(RELSTORAGE_BLOB_CACHE_SIZE_CHECK)
+ blob-cache-size-check-external $(RELSTORAGE_BLOB_CACHE_SIZE_CHECK_EXTERNAL)
+ blob-chunk-size $(RELSTORAGE_BLOB_CHUNK_SIZE)
+
+ dsn $(RELSTORAGE_DSN)
+
+
+ mount-point /
+
diff --git a/backend/container/skeleton/etc/relstorage_pack.conf b/backend/container/skeleton/etc/relstorage_pack.conf
new file mode 100644
index 0000000..ad22a2a
--- /dev/null
+++ b/backend/container/skeleton/etc/relstorage_pack.conf
@@ -0,0 +1,6 @@
+
+ pack-gc true
+
+ dsn $(RELSTORAGE_DSN)
+
+
diff --git a/backend/container/skeleton/etc/site.zcml b/backend/container/skeleton/etc/site.zcml
new file mode 100644
index 0000000..0eeb830
--- /dev/null
+++ b/backend/container/skeleton/etc/site.zcml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/backend/container/skeleton/etc/zeo.conf b/backend/container/skeleton/etc/zeo.conf
new file mode 100644
index 0000000..4dc1821
--- /dev/null
+++ b/backend/container/skeleton/etc/zeo.conf
@@ -0,0 +1,36 @@
+%define INSTANCE /app
+instancehome $INSTANCE
+
+%define CLIENTHOME $(CLIENT_HOME)
+clienthome $CLIENTHOME
+
+debug-mode $(DEBUG_MODE)
+security-policy-implementation $(SECURITY_POLICY_IMPLEMENTATION)
+verbose-security $(VERBOSE_SECURITY)
+default-zpublisher-encoding $(DEFAULT_ZPUBLISHER_ENCODING)
+
+
+ CHAMELEON_CACHE $INSTANCE/var/cache
+
+
+
+ form-memory-limit $(ZOPE_FORM_MEMORY_LIMIT)
+
+
+
+ # Main database
+ cache-size $(ZODB_CACHE_SIZE)
+
+ name zeostorage
+ var $INSTANCE/var
+ blob-dir $INSTANCE/var/blobstorage
+ read-only $(ZEO_READ_ONLY)
+ read-only-fallback $(ZEO_CLIENT_READ_ONLY_FALLBACK)
+ shared-blob-dir $(ZEO_SHARED_BLOB_DIR)
+ server $(ZEO_ADDRESS)
+ storage $(ZEO_STORAGE)
+ cache-size $(ZEO_CLIENT_CACHE_SIZE)
+ drop-cache-rather-verify $(ZEO_DROP_CACHE_RATHER_VERIFY)
+
+ mount-point /
+
diff --git a/backend/container/skeleton/etc/zope.conf b/backend/container/skeleton/etc/zope.conf
new file mode 100644
index 0000000..ba9734d
--- /dev/null
+++ b/backend/container/skeleton/etc/zope.conf
@@ -0,0 +1,34 @@
+%define INSTANCE /app
+instancehome $INSTANCE
+
+%define CLIENTHOME $(CLIENT_HOME)
+clienthome $CLIENTHOME
+
+debug-mode $(DEBUG_MODE)
+security-policy-implementation $(SECURITY_POLICY_IMPLEMENTATION)
+verbose-security $(VERBOSE_SECURITY)
+default-zpublisher-encoding $(DEFAULT_ZPUBLISHER_ENCODING)
+
+
+ CHAMELEON_CACHE $INSTANCE/var/cache
+
+
+
+ form-memory-limit $(ZOPE_FORM_MEMORY_LIMIT)
+ form-disk-limit $(ZOPE_FORM_DISK_LIMIT)
+ form-memfile-limit $(ZOPE_FORM_MEMFILE_LIMIT)
+
+
+
+ # Main database
+ cache-size $(ZODB_CACHE_SIZE)
+ # Blob-enabled FileStorage database
+
+ blob-dir $INSTANCE/var/blobstorage
+ # FileStorage database
+
+ path $INSTANCE/var/filestorage/Data.fs
+
+
+ mount-point /
+
diff --git a/backend/src/pythonbrasil/site/profiles/default/registry/.gitkeep b/backend/container/skeleton/etc/zope.conf.d/.gitkeep
similarity index 100%
rename from backend/src/pythonbrasil/site/profiles/default/registry/.gitkeep
rename to backend/container/skeleton/etc/zope.conf.d/.gitkeep
diff --git a/backend/container/skeleton/etc/zope.ini b/backend/container/skeleton/etc/zope.ini
new file mode 100644
index 0000000..161cd5a
--- /dev/null
+++ b/backend/container/skeleton/etc/zope.ini
@@ -0,0 +1,72 @@
+[app:zope]
+use = egg:Zope#main
+zope_conf = %(here)s/%(config_file)s
+
+[server:main]
+use = egg:waitress#main
+host = 0.0.0.0
+port = 8080
+threads = 2
+clear_untrusted_proxy_headers = false
+max_request_body_size = 1073741824
+
+
+[filter:translogger]
+use = egg:Paste#translogger
+setup_console_handler = False
+
+[pipeline:main]
+pipeline =
+ egg:Zope#httpexceptions
+ translogger
+ zope
+
+[loggers]
+keys = root, waitress.queue, waitress, wsgi
+
+[handlers]
+keys = accesslog, eventlog
+
+[formatters]
+keys = generic, message
+
+[formatter_generic]
+format = %(asctime)s %(levelname)s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
+datefmt = %Y-%m-%d %H:%M:%S
+
+[formatter_message]
+format = %(message)s
+
+[logger_root]
+level = INFO
+handlers = eventlog
+
+[logger_waitress.queue]
+level = INFO
+handlers = eventlog
+qualname = waitress.queue
+propagate = 0
+
+[logger_waitress]
+level = INFO
+handlers = eventlog
+qualname = waitress
+propagate = 0
+
+[logger_wsgi]
+level = WARN
+handlers = accesslog
+qualname = wsgi
+propagate = 0
+
+[handler_accesslog]
+class = StreamHandler
+args = (sys.stdout,)
+level = INFO
+formatter = message
+
+[handler_eventlog]
+class = StreamHandler
+args = (sys.stderr,)
+level = INFO
+formatter = generic
diff --git a/backend/container/skeleton/inituser b/backend/container/skeleton/inituser
new file mode 100644
index 0000000..bb09481
--- /dev/null
+++ b/backend/container/skeleton/inituser
@@ -0,0 +1 @@
+admin:{SHA}0DPiKuNIrrVmD8IUCuw1hQxNqZc=
\ No newline at end of file
diff --git a/backend/container/skeleton/scripts/cors.py b/backend/container/skeleton/scripts/cors.py
new file mode 100644
index 0000000..d8ca0b3
--- /dev/null
+++ b/backend/container/skeleton/scripts/cors.py
@@ -0,0 +1,53 @@
+import os
+
+
+CORS_TEMPLATE = """
+
+
+
+
+"""
+
+
+def main(conf="/app/etc/package-includes/999-cors-overrides.zcml"):
+ """Configure CORS Policies"""
+ if not [e for e in os.environ if e.startswith("CORS_")]:
+ return
+
+ allow_origin = os.environ.get(
+ "CORS_ALLOW_ORIGIN", "http://localhost:3000,http://127.0.0.1:3000"
+ )
+ allow_methods = os.environ.get(
+ "CORS_ALLOW_METHODS", "DELETE,GET,OPTIONS,PATCH,POST,PUT"
+ )
+ allow_credentials = os.environ.get("CORS_ALLOW_CREDENTIALS", "true")
+ expose_headers = os.environ.get("CORS_EXPOSE_HEADERS", "Content-Length,X-My-Header")
+ allow_headers = os.environ.get(
+ "CORS_ALLOW_HEADERS",
+ "Accept,Authorization,Content-Type,X-Custom-Header,Lock-Token",
+ )
+ max_age = os.environ.get("CORS_MAX_AGE", "3600")
+ cors_conf = CORS_TEMPLATE.format(
+ allow_origin=allow_origin,
+ allow_methods=allow_methods,
+ allow_credentials=allow_credentials,
+ expose_headers=expose_headers,
+ allow_headers=allow_headers,
+ max_age=max_age,
+ )
+ with open(conf, "w") as cors_file:
+ cors_file.write(cors_conf)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/backend/container/skeleton/scripts/pack.py b/backend/container/skeleton/scripts/pack.py
new file mode 100644
index 0000000..60a5dbb
--- /dev/null
+++ b/backend/container/skeleton/scripts/pack.py
@@ -0,0 +1,4 @@
+from Zope2 import DB
+
+
+DB.pack()
diff --git a/backend/mx.ini b/backend/mx.ini
deleted file mode 100644
index 3d90d94..0000000
--- a/backend/mx.ini
+++ /dev/null
@@ -1,17 +0,0 @@
-; This is a mxdev configuration file
-; it can be used to override versions of packages already defined in the
-; constraints files and to add new packages from VCS like git.
-; to learn more about mxdev visit https://pypi.org/project/mxdev/
-
-[settings]
-main-package = -e .[test]
-; example how to override a package version
-version-overrides =
- plone.volto==5.0.3
-
-; example section to use packages from git
-; [example.contenttype]
-; url = https://github.com/collective/example.contenttype.git
-; pushurl = git@github.com:collective/example.contenttype.git
-; extras = test
-; branch = feature-7
diff --git a/backend/news/+refactor.internal b/backend/news/+refactor.internal
new file mode 100644
index 0000000..81a5faf
--- /dev/null
+++ b/backend/news/+refactor.internal
@@ -0,0 +1 @@
+Refactor codebase to use UV @ericof
diff --git a/backend/news/+social.feature b/backend/news/+social.feature
new file mode 100644
index 0000000..c5ebee3
--- /dev/null
+++ b/backend/news/+social.feature
@@ -0,0 +1 @@
+Add plonegovbr.socialmedia as a dependency. @ericof
diff --git a/backend/news/.changelog_template.jinja b/backend/news/.changelog_template.jinja
index 678bfa1..b35bff3 100644
--- a/backend/news/.changelog_template.jinja
+++ b/backend/news/.changelog_template.jinja
@@ -1,9 +1,9 @@
-{% if sections[] %}
-{% for category, val in definitions.items() if category in sections[] %}
+{% if sections[""] %}
+{% for category, val in definitions.items() if category in sections[""] %}
### {{ definitions[category]['name'] }}
-{% for text, values in sections[][category].items() %}
+{% for text, values in sections[""][category].items() %}
- {{ text }} {{ values|join(', ') }}
{% endfor %}
@@ -12,4 +12,4 @@
No significant changes.
-{% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index c982aa9..a262749 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -1,15 +1,543 @@
-# Generated from:
-# https://github.com/plone/meta/tree/main/config/default
-# See the inline comments on how to expand/tweak this configuration file
+[project]
+name = "pythonbrasil.site"
+dynamic = ["version"]
+description = "Encontro da comunidade Python Brasileira"
+readme = "README.md"
+license = "GPL-2.0-only"
+requires-python = ">=3.12"
+authors = [
+ { name = "PloneGov-BR", email = "gov@plone.org.br" },
+]
+keywords = [
+ "CMS",
+ "Plone",
+ "Python",
+]
+classifiers = [
+ "Development Status :: 3 - Alpha",
+ "Environment :: Web Environment",
+ "Framework :: Plone","Framework :: Plone :: 6.1",
+ "Framework :: Plone :: Addon",
+ "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python","Programming Language :: Python :: 3.12",
+ "Programming Language :: Python","Programming Language :: Python :: 3.13",
+]
+dependencies = [
+ "Products.CMFPlone==6.1.1",
+ "plone.api",
+ "plone.restapi",
+ "plone.volto",
+ "plonegovbr.socialmedia>=2.0.0a5",
+ "collective.volto.formsupport",
+ "collective.honeypot",
+ "plone.app.upgrade",
+]
+
+
+[dependency-groups]
+build = [
+ "hatchling",
+ "wheel",
+]
+test = [
+ "horse-with-no-namespace>=20250408.0",
+ "mypy>=1.15.0",
+ "plone.app.testing",
+ "plone.restapi[test]",
+ "pytest",
+ "pytest-cov==6.1.1",
+ "pytest-plone>=1.0.0a1",
+]
+container = [
+ "plone.app.upgrade",
+ "psycopg2==2.9.10",
+ "relstorage==4.1.1",
+ "zeo==6.0.0",
+]
+
+[project.urls]
+Homepage = "https://github.com/pythonbrasil/pybr25-site"
+PyPI = "https://pypi.org/project/pythonbrasil.site"
+Source = "https://github.com/pythonbrasil/pybr25-site"
+Tracker = "https://github.com/pythonbrasil/pybr25-site/issues"
+
+
+[project.entry-points."plone.autoinclude.plugin"]
+target = "plone"
+
+[tool.uv]
+managed = true
+default-groups = ["build", "test"]
+constraint-dependencies = [
+ "AccessControl==7.2",
+ "Acquisition==6.1",
+ "alabaster==0.7.14; python_version == '3.9'",
+ "alabaster==1.0.0; python_version > '3.9'",
+ "argcomplete==3.5.2",
+ "argh==0.31.3",
+ "async-generator==1.10",
+ "attrs==24.2.0",
+ "AuthEncoding==6.0",
+ "Babel==2.16.0",
+ "backports.cached-property==1.0.2",
+ "backports.tarfile==1.2.0",
+ "beautifulsoup4==4.12.3",
+ "bleach==6.2.0",
+ "borg.localrole==3.1.11",
+ "BTrees==6.1",
+ "build==1.2.2post1",
+ "cachecontrol==0.14.1",
+ "cached-property==2.0.1",
+ "certifi==2024.12.14",
+ "cffi==1.17.1",
+ "Chameleon==4.4.4",
+ "charset-normalizer==3.4.1",
+ "check-manifest==0.50",
+ "click-default-group==1.2.4",
+ "click==8.1.7",
+ "cmarkgfm==2024.11.20",
+ "collective.MockMailHost==3.0.0",
+ "collective.monkeypatcher==2.0.0",
+ "collective.recipe.omelette==2.0.0",
+ "collective.recipe.template==2.2",
+ "collective.recipe.vscode==0.1.9",
+ "collective.xmltestreport==2.0.2",
+ "collective.z3cform.datagridfield==3.0.3",
+ "colorama==0.4.6",
+ "colorama==0.4.6",
+ "commonmark==0.9.1",
+ "configparser==7.1.0",
+ "coverage==7.6.9",
+ "cryptography==44.0.0",
+ "cssselect==1.2.0",
+ "DateTime==5.5",
+ "decorator==5.1.1",
+ "Deprecated==1.2.15",
+ "diazo==2.0.3",
+ "distro==1.9.0",
+ "DocumentTemplate==4.6",
+ "docutils==0.20.1; python_version == '3.9'",
+ "docutils==0.21.2; python_version > '3.9'",
+ "exceptiongroup==1.2.2",
+ "ExtensionClass==6.0",
+ "fancycompleter==0.9.1",
+ "feedparser==6.0.11",
+ "filelock==3.16.1",
+ "five.customerize==3.0.0",
+ "five.intid==2.0.1",
+ "five.localsitemanager==4.0",
+ "furl==2.1.3",
+ "furo==2024.8.6",
+ "future==1.0.0",
+ "gitdb==4.0.11",
+ "GitPython==3.1.43",
+ "gunicorn==23.0.0",
+ "h11==0.14.0",
+ "horse-with-no-namespace>=20250408.0",
+ "httplib2==0.22.0",
+ "i18ndude==6.2.1",
+ "icalendar==6.1.1",
+ "idna==3.10",
+ "imagesize==1.4.1",
+ "importlib-metadata==8.5.0",
+ "importlib-resources==6.4.5",
+ "incremental==24.7.2",
+ "iniconfig==2.0.0",
+ "jaraco.classes==3.4.0",
+ "jaraco.context==6.0.1",
+ "jaraco.functools==4.1.0",
+ "jeepney==0.8.0",
+ "Jinja2==3.1.5",
+ "jsonschema-specifications==2024.10.1",
+ "jsonschema==4.23.0",
+ "keyring==25.5.0",
+ "legacy-cgi==2.6.2",
+ "lockfile==0.12.2",
+ "lxml-html-clean==0.4.1",
+ "lxml==5.3.0",
+ "manuel==1.13.0",
+ "markdown-it-py==3.0.0",
+ "Markdown==3.7",
+ "MarkupSafe==3.0.2",
+ "mdurl==0.1.2",
+ "Missing==5.0",
+ "mock==5.1.0",
+ "more-itertools==10.5.0",
+ "mr.developer==2.0.2",
+ "msgpack==1.1.0",
+ "MultiMapping==5.0",
+ "multipart==1.2.1",
+ "mxdev==4.0.3",
+ "mypy>=1.15.0",
+ "natsort==8.4.0",
+ "nh3==0.2.19",
+ "nt-svcutils==2.13.0",
+ "oauthlib==3.2.2",
+ "orderedmultidict==1.0.1",
+ "outcome==1.3.0post0",
+ "overrides==7.7.0",
+ "packaging==24.2",
+ "Paste==3.10.1",
+ "PasteDeploy==3.1.0",
+ "pdbpp==0.10.3",
+ "pep440==0.1.2",
+ "pep517==0.13.1",
+ "Persistence==5.1",
+ "persistent==6.1",
+ "piexif==1.1.3",
+ "Pillow==11.0.0",
+ "pip==25.0.1",
+ "pkginfo==1.10.0",
+ "plone.alterego==2.0.1",
+ "plone.api==2.5.0",
+ "plone.app.blocks==7.0.1",
+ "plone.app.caching==4.1.0",
+ "plone.app.content==4.1.9",
+ "plone.app.contentlisting==3.0.5",
+ "plone.app.contentmenu==3.0.7",
+ "plone.app.contentrules==5.0.6",
+ "plone.app.contenttypes==4.0.5",
+ "plone.app.customerize==2.0.2",
+ "plone.app.debugtoolbar==1.4.0",
+ "plone.app.dexterity==4.0.4",
+ "plone.app.discussion==5.0.0",
+ "plone.app.drafts==2.0.0",
+ "plone.app.event==5.2.1",
+ "plone.app.i18n==4.0.1",
+ "plone.app.intid==2.0.0",
+ "plone.app.iterate==6.1.0",
+ "plone.app.jquerytools==1.9.5",
+ "plone.app.layout==5.0.2",
+ "plone.app.linkintegrity==4.0.6",
+ "plone.app.locales==6.0.30",
+ "plone.app.lockingbehavior==2.0.2",
+ "plone.app.mosaic==3.2.1",
+ "plone.app.multilingual==8.2.3",
+ "plone.app.portlets==6.0.1",
+ "plone.app.querystring==2.1.3",
+ "plone.app.redirector==3.0.4",
+ "plone.app.registry==2.0.6",
+ "plone.app.relationfield==4.0.2",
+ "plone.app.robotframework==2.1.5",
+ "plone.app.standardtiles==3.2.1",
+ "plone.app.testing==7.1.1",
+ "plone.app.textfield==3.0.0",
+ "plone.app.theming==5.0.12",
+ "plone.app.tiles==4.0.1",
+ "plone.app.upgrade==3.2.0",
+ "plone.app.users==3.1.1",
+ "plone.app.uuid==2.2.3",
+ "plone.app.versioningbehavior==2.0.4",
+ "plone.app.viewletmanager==4.0.4",
+ "plone.app.vocabularies==6.0.2",
+ "plone.app.widgets==5.0.2",
+ "plone.app.workflow==5.0.4",
+ "plone.app.z3cform==4.7.4",
+ "plone.autoform==2.0.3",
+ "plone.autoinclude==2.0.3",
+ "plone.base==2.0.3",
+ "plone.batching==2.0.6",
+ "plone.behavior==2.0.1",
+ "plone.browserlayer==3.0.2",
+ "plone.cachepurging==3.0.2",
+ "plone.caching==2.0.1",
+ "plone.classicui==1.0.0",
+ "plone.contentrules==3.0.1",
+ "plone.dexterity==3.0.7",
+ "plone.distribution==3.1.1",
+ "plone.event==2.0.2",
+ "plone.exportimport==1.1.0",
+ "plone.folder==4.0.1",
+ "plone.formwidget.autocomplete==1.4.1",
+ "plone.formwidget.namedfile==3.1.1",
+ "plone.formwidget.recurrence==3.0.5",
+ "plone.i18n==5.1.0",
+ "plone.indexer==2.0.1",
+ "plone.intelligenttext==4.0.1",
+ "plone.jsonserializer==0.9.11",
+ "plone.keyring==4.0.2",
+ "plone.locking==3.0.2",
+ "plone.memoize==3.0.3",
+ "plone.namedfile==7.0.1",
+ "plone.outputfilters==5.0.4",
+ "plone.portlet.collection==4.0.4",
+ "plone.portlet.static==4.0.4",
+ "plone.portlets==3.0.2",
+ "plone.protect==5.0.3",
+ "plone.recipe.command==1.1",
+ "plone.recipe.zeoserver==3.0.4",
+ "plone.recipe.zope2instance==8.0.0",
+ "plone.registry==2.0.1",
+ "plone.releaser==2.4.1",
+ "plone.reload==4.0.0",
+ "plone.resource==3.0.2",
+ "plone.resourceeditor==4.0.1",
+ "plone.rest==5.0.0",
+ "plone.restapi==9.13.3",
+ "plone.rfc822==3.0.1",
+ "plone.scale==4.1.4",
+ "plone.schema==2.0.2",
+ "plone.schemaeditor==4.0.11",
+ "plone.session==4.0.4",
+ "plone.staticresources==2.2.5",
+ "plone.stringinterp==2.0.2",
+ "plone.subrequest==2.0.5",
+ "plone.supermodel==2.0.4",
+ "plone.testing==9.0.5",
+ "plone.theme==4.0.3",
+ "plone.tiles==2.3.1",
+ "plone.transformchain==3.0.1",
+ "plone.uuid==2.0.1",
+ "plone.versioncheck==1.8.2",
+ "plone.volto==5.0.4",
+ "plone.z3cform==2.0.4",
+ "Plone==6.1.1",
+ "plonetheme.barceloneta==3.2.3",
+ "plonegovbr.socialmedia==2.0.0a5",
+ "pluggy==1.5.0",
+ "Products.BTreeFolder2==5.1",
+ "Products.CMFCore==3.7",
+ "Products.CMFDiffTool==4.0.4",
+ "Products.CMFDynamicViewFTI==7.0.2",
+ "Products.CMFEditions==4.0.5",
+ "Products.CMFPlacefulWorkflow==3.0.5",
+ "Products.CMFPlone==6.1.1",
+ "Products.CMFUid==4.2",
+ "Products.DateRecurringIndex==3.0.1",
+ "Products.DCWorkflow==3.0",
+ "Products.ExtendedPathIndex==4.0.1",
+ "Products.ExternalMethod==6.0",
+ "Products.GenericSetup==5.0.0",
+ "Products.isurlinportal==3.0.0",
+ "Products.MailHost==6.0",
+ "Products.MimetypesRegistry==3.0.1",
+ "Products.PDBDebugMode==2.0",
+ "Products.PlonePAS==8.0.5",
+ "Products.PluggableAuthService==3.0",
+ "Products.PluginRegistry==2.0",
+ "Products.PortalTransforms==4.1.1",
+ "Products.PrintingMailHost==1.1.7",
+ "Products.PythonScripts==5.1",
+ "Products.Sessions==5.0",
+ "Products.SiteErrorLog==6.0",
+ "Products.StandardCacheManagers==5.0",
+ "Products.statusmessages==5.0.6",
+ "Products.validation==3.0.0",
+ "Products.ZCatalog==7.1",
+ "Products.ZopeVersionControl==4.1",
+ "progress==1.6",
+ "prompt-toolkit==3.0.48",
+ "psycopg2==2.9.10",
+ "py==1.11.0",
+ "pycparser==2.22",
+ "PyGithub==2.5.0",
+ "Pygments==2.19.1",
+ "PyJWT==2.10.1",
+ "PyNaCl==1.5.0",
+ "pyOpenSSL==24.3.0",
+ "pyparsing==3.2.0",
+ "pyproject-hooks==1.2.0",
+ "pyrepl==0.9.0",
+ "pyroma==4.2",
+ "pyrsistent==0.20.0",
+ "PySocks==1.7.1",
+ "pytest-cov==6.1.1",
+ "pytest-plone>=1.0.0a1",
+ "pytest==7.4.4",
+ "python-dateutil==2.9.0.post0",
+ "python-dotenv==1.0.1",
+ "python-gettext==5.0",
+ "pytz==2024.2",
+ "pywin32-ctypes==0.2.3; platform_system == \"Windows\"",
+ "PyYAML==6.0.2",
+ "readme-renderer==44.0",
+ "Record==4.1",
+ "referencing==0.35.1",
+ "relstorage==4.1.1",
+ "repoze.xmliter==1.0b1",
+ "requests-toolbelt==1.0.0",
+ "requests==2.32.3",
+ "responses==0.25.3",
+ "RestrictedPython==8.0",
+ "rfc3986==2.0.0",
+ "rich==13.9.4",
+ "robotframework-assertion-engine==3.0.3",
+ "robotframework-browser==19.3.1",
+ "robotframework-debuglibrary==2.5.0",
+ "robotframework-lsp==1.10.1",
+ "robotframework-pythonlibcore==4.4.1",
+ "robotframework-selenium2library==3.0.0",
+ "robotframework-selenium2screenshots==0.8.1",
+ "robotframework-seleniumlibrary==6.1.3",
+ "robotframework-seleniumtestability==2.1.0",
+ "robotframework==6.0.2",
+ "robotsuite==2.3.2",
+ "roman==5.0",
+ "rpds-py==0.22.3",
+ "SecretStorage==3.3.3",
+ "seedir==0.5.0",
+ "selenium==4.9.1",
+ "setuptools==75.8.2",
+ "sgmllib3k==1.0.0",
+ "simplejson==3.19.3",
+ "six==1.17.0",
+ "smmap==5.0.1",
+ "sniffio==1.3.1",
+ "snowballstemmer==2.2.0",
+ "sortedcontainers==2.4.0",
+ "soupsieve==2.6",
+ "sphinx-basic-ng==1.0.0b2",
+ "Sphinx==7.4.7; python_version == '3.9'",
+ "Sphinx==8.1.3; python_version > '3.9'",
+ "sphinxcontrib-applehelp==2.0.0",
+ "sphinxcontrib-devhelp==2.0.0",
+ "sphinxcontrib-htmlhelp==2.1.0",
+ "sphinxcontrib-jsmath==1.0.1",
+ "sphinxcontrib-qthelp==2.0.0",
+ "sphinxcontrib-serializinghtml==2.0.0",
+ "stdlib-list==0.11.0",
+ "tempstorage==6.0",
+ "toml==0.10.2",
+ "tomli==2.2.1",
+ "towncrier==24.8.0",
+ "transaction==5.0",
+ "trio-websocket==0.11.1",
+ "trio==0.27.0",
+ "trove-classifiers==2025.2.18.16",
+ "twine==5.1.1",
+ "types-PyYAML==6.0.12.10",
+ "types-toml==0.10.8.5",
+ "typing-extensions==4.12.2",
+ "tzdata==2025.1",
+ "Unidecode==1.3.8",
+ "urllib3-secure-extra==0.1.0",
+ "urllib3==2.3.0",
+ "wadllib==2.0.0",
+ "waitress==3.0.2",
+ "watchdog==6.0.0",
+ "wcwidth==0.2.13",
+ "webencodings==0.5.1",
+ "WebOb==1.8.9",
+ "webresource==1.2",
+ "WebTest==3.0.3",
+ "wheel==0.45.1",
+ "wmctrl==0.5",
+ "wrapt==1.17.0",
+ "WSGIProxy2==0.5.1",
+ "wsproto==1.2.0",
+ "z3c.caching==3.0",
+ "z3c.checkversions==2.1",
+ "z3c.dependencychecker==2.15",
+ "z3c.form==5.1",
+ "z3c.formwidget.query==2.0.0",
+ "z3c.jbot==2.0",
+ "z3c.objpath==2.0",
+ "z3c.pt==4.4",
+ "z3c.relationfield==2.0.0",
+ "z3c.unconfigure==2.1",
+ "z3c.zcmlhook==2.0",
+ "zc.buildout==4.1.4",
+ "zc.lockfile==3.0.post1",
+ "zc.recipe.egg==2.0.7",
+ "zc.recipe.testrunner==3.1",
+ "zc.relation==2.0",
+ "ZConfig==4.2",
+ "zdaemon==5.1",
+ "ZEO==6.0.0",
+ "zeo==6.0.0",
+ "zest.pocompile==2.0.0",
+ "zest.releaser==9.5.0",
+ "zestreleaser.towncrier==1.3.0",
+ "zExceptions==5.0",
+ "zipp==3.21.0",
+ "ZODB3==3.11.0",
+ "ZODB==6.0",
+ "zodbpickle==4.1.1",
+ "zodbupdate==2.0",
+ "zodbverify==1.2.0",
+ "zope.annotation==5.0",
+ "zope.app.locales==5.0",
+ "zope.browser==3.0",
+ "zope.browsermenu==5.0",
+ "zope.browserpage==5.0",
+ "zope.browserresource==5.1",
+ "zope.cachedescriptors==5.0",
+ "zope.component==6.0",
+ "zope.componentvocabulary==2.3.0",
+ "zope.configuration==6.0",
+ "zope.container==6.1",
+ "zope.contentprovider==6.0",
+ "zope.contenttype==5.1",
+ "zope.copy==5.0",
+ "zope.datetime==5.0.0",
+ "zope.deferredimport==5.0",
+ "zope.deprecation==5.1",
+ "zope.dottedname==6.0",
+ "zope.event==5.0",
+ "zope.exceptions==5.2",
+ "zope.filerepresentation==6.0",
+ "zope.globalrequest==2.0",
+ "zope.hookable==7.0",
+ "zope.i18n==5.2",
+ "zope.i18nmessageid==7.0",
+ "zope.interface==7.2",
+ "zope.intid==5.0",
+ "zope.keyreference==6.0",
+ "zope.lifecycleevent==5.0",
+ "zope.location==5.0",
+ "zope.mkzeoinstance==6.0",
+ "zope.pagetemplate==5.1",
+ "zope.processlifetime==3.0",
+ "zope.proxy==6.1",
+ "zope.ptresource==5.0",
+ "zope.publisher==7.3",
+ "zope.pytestlayer==8.2",
+ "zope.ramcache==3.0",
+ "zope.schema==7.0.1",
+ "zope.security==7.3",
+ "zope.sendmail==6.2",
+ "zope.sequencesort==5.0",
+ "zope.site==5.0",
+ "zope.size==5.0",
+ "zope.structuredtext==5.0",
+ "zope.tal==5.0.1",
+ "zope.tales==6.0",
+ "zope.testbrowser==7.0",
+ "zope.testing==5.0.1",
+ "zope.testrunner==7.2",
+ "zope.traversing==5.0",
+ "zope.viewlet==5.0",
+ "Zope2==4.0",
+ "Zope==5.13",
+ "ZopeUndo==6.0",
+]
+
+[tool.hatch.version]
+path = "src/pythonbrasil/site/__init__.py"
+
[build-system]
-requires = ["setuptools>=68.2"]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.hatch.build]
+strict-naming = true
+
+[tool.hatch.build.targets.sdist]
+exclude = [
+ "/.github",
+]
+
+[tool.hatch.build.targets.wheel]
+packages = ["src/pythonbrasil"]
[tool.towncrier]
directory = "news/"
-filename = "CHANGES.md"
+filename = "CHANGELOG.md"
start_string = "\n"
title_format = "## {version} ({project_date})"
template = "news/.changelog_template.jinja"
+issue_format = "[#{issue}](https://github.com/pythonbrasil/pybr25-site/issues/{issue})"
underlines = ["", "", ""]
[[tool.towncrier.type]]
@@ -42,129 +570,73 @@ directory = "tests"
name = "Tests"
showcontent = true
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# towncrier_extra_lines = """
-# extra_configuration
-# """
-##
-
-[tool.isort]
-profile = "plone"
-
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# isort_extra_lines = """
-# extra_configuration
-# """
-##
-
-[tool.black]
-target-version = ["py38"]
-
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# black_extra_lines = """
-# extra_configuration
-# """
-##
-
-[tool.codespell]
-ignore-words-list = "discreet,vew"
-skip = "*.po,*.min.js"
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# codespell_ignores = "foo,bar"
-# codespell_skip = "*.po,*.map,package-lock.json"
-##
-
-[tool.dependencychecker]
-Zope = [
- # Zope own provided namespaces
- 'App', 'OFS', 'Products.Five', 'Products.OFSP', 'Products.PageTemplates',
- 'Products.SiteAccess', 'Shared', 'Testing', 'ZPublisher', 'ZTUtils',
- 'Zope2', 'webdav', 'zmi',
- # ExtensionClass own provided namespaces
- 'ExtensionClass', 'ComputedAttribute', 'MethodObject',
- # Zope dependencies
- 'AccessControl', 'Acquisition', 'AuthEncoding', 'beautifulsoup4', 'BTrees',
- 'cffi', 'Chameleon', 'DateTime', 'DocumentTemplate',
- 'MultiMapping', 'multipart', 'PasteDeploy', 'Persistence', 'persistent',
- 'pycparser', 'python-gettext', 'pytz', 'RestrictedPython', 'roman',
- 'soupsieve', 'transaction', 'waitress', 'WebOb', 'WebTest', 'WSGIProxy2',
- 'z3c.pt', 'zc.lockfile', 'ZConfig', 'zExceptions', 'ZODB', 'zodbpickle',
- 'zope.annotation', 'zope.browser', 'zope.browsermenu', 'zope.browserpage',
- 'zope.browserresource', 'zope.cachedescriptors', 'zope.component',
- 'zope.configuration', 'zope.container', 'zope.contentprovider',
- 'zope.contenttype', 'zope.datetime', 'zope.deferredimport',
- 'zope.deprecation', 'zope.dottedname', 'zope.event', 'zope.exceptions',
- 'zope.filerepresentation', 'zope.globalrequest', 'zope.hookable',
- 'zope.i18n', 'zope.i18nmessageid', 'zope.interface', 'zope.lifecycleevent',
- 'zope.location', 'zope.pagetemplate', 'zope.processlifetime', 'zope.proxy',
- 'zope.ptresource', 'zope.publisher', 'zope.schema', 'zope.security',
- 'zope.sequencesort', 'zope.site', 'zope.size', 'zope.structuredtext',
- 'zope.tal', 'zope.tales', 'zope.testbrowser', 'zope.testing',
- 'zope.traversing', 'zope.viewlet'
+[tool.ruff]
+target-version = "py312"
+line-length = 88
+fix = true
+lint.select = [
+ # flake8-2020
+ "YTT",
+ # flake8-bandit
+ "S",
+ # flake8-bugbear
+ "B",
+ # flake8-builtins
+ "A",
+ # flake8-comprehensions
+ "C4",
+ # flake8-debugger
+ "T10",
+ # flake8-simplify
+ "SIM",
+ # mccabe
+ "C90",
+ # pycodestyle
+ "E", "W",
+ # pyflakes
+ "F",
+ # pygrep-hooks
+ "PGH",
+ # pyupgrade
+ "UP",
+ # ruff
+ "RUF",
]
-'Products.CMFCore' = [
- 'docutils', 'five.localsitemanager', 'Missing', 'Products.BTreeFolder2',
- 'Products.GenericSetup', 'Products.MailHost', 'Products.PythonScripts',
- 'Products.StandardCacheManagers', 'Products.ZCatalog', 'Record',
- 'zope.sendmail', 'Zope'
+lint.ignore = [
+ # DoNotAssignLambda
+ "E731",
]
-'plone.base' = [
- 'plone.batching', 'plone.registry', 'plone.schema','plone.z3cform',
- 'Products.CMFCore', 'Products.CMFDynamicViewFTI',
-]
-python-dateutil = ['dateutil']
-pytest-plone = ['pytest', 'plone.testing', 'plone.app.testing']
-ignore-packages = ['plone.app.iterate', 'plone.app.upgrade', 'plone.volto', 'zestreleaser.towncrier', 'zest.releaser', 'pytest-cov']
-
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# dependencies_ignores = "['zestreleaser.towncrier']"
-# dependencies_mappings = [
-# "gitpython = ['git']",
-# "pygithub = ['github']",
-# ]
-##
+
+[tool.ruff.lint.isort]
+case-sensitive = false
+no-sections = true
+force-single-line = true
+from-first = true
+lines-after-imports = 2
+lines-between-types = 1
+order-by-type = false
+
+[tool.ruff.format]
+preview = true
+
+[tool.ruff.lint.per-file-ignores]
+"tests/*" = ["E501", "RUF001", "S101"]
[tool.check-manifest]
ignore = [
".editorconfig",
".flake8",
- ".meta.toml",
- ".pre-commit-config.yaml",
"dependabot.yml",
"mx.ini",
- "tox.ini",
-
]
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# check_manifest_ignores = """
-# "*.map.js",
-# "*.pyc",
-# """
-# check_manifest_extra_lines = """
-# ignore-bad-ideas = [
-# "some/test/file/PKG-INFO",
-# ]
-# """
-##
-
-
-##
-# Add extra configuration options in .meta.toml:
-# [pyproject]
-# extra_lines = """
-# _your own configuration lines_
-# """
-##
+[tool.pytest.ini_options]
+testpaths = ["tests"]
+
+[tool.coverage.run]
+source_pkgs = ["pythonbrasil.site", "tests"]
+branch = true
+parallel = true
+omit = [
+ "src/pythonbrasil/site/locales/*.py",
+]
\ No newline at end of file
diff --git a/backend/requirements-docker.txt b/backend/requirements-docker.txt
deleted file mode 100644
index da44320..0000000
--- a/backend/requirements-docker.txt
+++ /dev/null
@@ -1 +0,0 @@
--c constraints.txt
diff --git a/backend/requirements.txt b/backend/requirements.txt
deleted file mode 100644
index da44320..0000000
--- a/backend/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
--c constraints.txt
diff --git a/backend/scripts/create_site.py b/backend/scripts/create_site.py
index 31fc102..09ac64a 100644
--- a/backend/scripts/create_site.py
+++ b/backend/scripts/create_site.py
@@ -35,7 +35,9 @@ def asbool(s):
request = app.REQUEST
-ifaces = [IBrowserLayer] + list(directlyProvidedBy(request))
+ifaces = [IBrowserLayer]
+for iface in directlyProvidedBy(request):
+ ifaces.append(iface)
directlyProvides(request, *ifaces)
@@ -47,9 +49,7 @@ def asbool(s):
payload = {
"title": "PythonBrasil 2025",
"profile_id": _DEFAULT_PROFILE,
- "extension_ids": [
- "pythonbrasil.site:default",
- ],
+ "distribution_name": "volto",
"setup_content": False,
"default_language": "pt-br",
"portal_timezone": "UTC",
@@ -63,8 +63,12 @@ def asbool(s):
if site_id not in app.objectIds():
site = addPloneSite(app, site_id, **payload)
transaction.commit()
+
+ portal_setup: SetupTool = site.portal_setup
+ portal_setup.runAllImportStepsFromProfile("profile-pythonbrasil.site:default")
+ transaction.commit()
+
if EXAMPLE_CONTENT:
- portal_setup: SetupTool = site.portal_setup
- portal_setup.runAllImportStepsFromProfile("pythonbrasil.site:initial")
+ portal_setup.runAllImportStepsFromProfile("profile-pythonbrasil.site:initial")
transaction.commit()
app._p_jar.sync()
diff --git a/backend/setup.py b/backend/setup.py
deleted file mode 100644
index 5a7f834..0000000
--- a/backend/setup.py
+++ /dev/null
@@ -1,77 +0,0 @@
-"""Installer for the pythonbrasil.site package."""
-
-from pathlib import Path
-from setuptools import find_packages
-from setuptools import setup
-
-
-long_description = f"""
-{Path("README.md").read_text()}\n
-{Path("CONTRIBUTORS.md").read_text()}\n
-{Path("CHANGES.md").read_text()}\n
-"""
-
-
-setup(
- name="pythonbrasil.site",
- version="1.0.0a0",
- description="Encontro da comunidade Python Brasileira",
- long_description=long_description,
- long_description_content_type="text/markdown",
- classifiers=[
- "Development Status :: 3 - Alpha",
- "Environment :: Web Environment",
- "Framework :: Plone",
- "Framework :: Plone :: Addon",
- "Framework :: Plone :: 6.0",
- "Programming Language :: Python",
- "Programming Language :: Python :: 3.11",
- "Programming Language :: Python :: 3.12",
- "Operating System :: OS Independent",
- "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
- ],
- keywords="Python Plone CMS",
- author="PloneGov-BR",
- author_email="ericof@plone.org",
- url="https://github.com/simplesconsultoria/pythonbrasil.site",
- project_urls={
- "PyPI": "https://pypi.org/project/pythonbrasil.site",
- "Source": "https://github.com/simplesconsultoria/pythonbrasil.site",
- "Tracker": "https://github.com/simplesconsultoria/pythonbrasil.site/issues",
- },
- license="GPL version 2",
- packages=find_packages("src", exclude=["ez_setup"]),
- namespace_packages=["pythonbrasil"],
- package_dir={"": "src"},
- include_package_data=True,
- zip_safe=False,
- python_requires=">=3.11",
- install_requires=[
- "setuptools",
- "plone.api",
- "plone.restapi",
- "plone.volto>=5.0.3",
- "plone.exportimport",
- "pas.plugins.authomatic>=2.0.0b2",
- "collective.volto.formsupport",
- "collective.honeypot",
- "collective.volto.otp",
- ],
- extras_require={
- "test": [
- "zest.releaser[recommended]",
- "zestreleaser.towncrier",
- "plone.app.testing",
- "plone.restapi[test]",
- "pytest",
- "pytest-cov",
- "pytest-plone>=0.5.0",
- ],
- },
- entry_points="""
- [z3c.autoinclude.plugin]
- target = plone
- [console_scripts]
- update_locale = pythonbrasil.site.locales.update:update_locale
- """,
-)
diff --git a/backend/src/pythonbrasil/__init__.py b/backend/src/pythonbrasil/__init__.py
index 5284146..26cfe40 100644
--- a/backend/src/pythonbrasil/__init__.py
+++ b/backend/src/pythonbrasil/__init__.py
@@ -1 +1,4 @@
-__import__("pkg_resources").declare_namespace(__name__)
+from pkgutil import extend_path
+
+
+__path__ = extend_path(__path__, __name__)
diff --git a/backend/src/pythonbrasil/site/__init__.py b/backend/src/pythonbrasil/site/__init__.py
index 11c0cc7..84db08e 100644
--- a/backend/src/pythonbrasil/site/__init__.py
+++ b/backend/src/pythonbrasil/site/__init__.py
@@ -5,6 +5,8 @@
import logging
+__version__ = "20250212.1"
+
PACKAGE_NAME = "pythonbrasil.site"
_ = MessageFactory(PACKAGE_NAME)
diff --git a/frontend/packages/volto-pythonbrasil-site/src/theme/blocks/_wrapper.scss b/backend/src/pythonbrasil/site/behaviors/__init__.py
similarity index 100%
rename from frontend/packages/volto-pythonbrasil-site/src/theme/blocks/_wrapper.scss
rename to backend/src/pythonbrasil/site/behaviors/__init__.py
diff --git a/backend/src/pythonbrasil/site/behaviors/configure.zcml b/backend/src/pythonbrasil/site/behaviors/configure.zcml
new file mode 100644
index 0000000..0523e45
--- /dev/null
+++ b/backend/src/pythonbrasil/site/behaviors/configure.zcml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/backend/src/pythonbrasil/site/behaviors/customizations.py b/backend/src/pythonbrasil/site/behaviors/customizations.py
new file mode 100644
index 0000000..faa089e
--- /dev/null
+++ b/backend/src/pythonbrasil/site/behaviors/customizations.py
@@ -0,0 +1,46 @@
+from plone.autoform import directives
+from plone.autoform.interfaces import IFormFieldProvider
+from plone.schema import JSONField
+from plone.supermodel import model
+from pythonbrasil.site import _
+from zope.interface import provider
+
+import json
+
+
+OBJECT_LIST_DEFAULT_VALUE = []
+
+OBJECT_LIST = json.dumps({
+ "type": "array",
+ "items": {
+ "type": "object",
+ },
+})
+
+
+@provider(IFormFieldProvider)
+class ISiteFooterCustomizationSettings(model.Schema):
+ """Site/Subsite footer properties behavior."""
+
+ model.fieldset(
+ "footer",
+ label=_("Rodapé"),
+ fields=[
+ "footer_links",
+ ],
+ )
+
+ directives.widget(
+ "footer_links",
+ frontendOptions={
+ "widget": "object_list",
+ "widgetProps": {"schemaName": "footerLinks"},
+ },
+ )
+ footer_links = JSONField(
+ title=_("Links"),
+ schema=OBJECT_LIST,
+ default=OBJECT_LIST_DEFAULT_VALUE,
+ required=False,
+ widget="",
+ )
diff --git a/backend/src/pythonbrasil/site/configure.zcml b/backend/src/pythonbrasil/site/configure.zcml
index ea88e3a..899b7ce 100644
--- a/backend/src/pythonbrasil/site/configure.zcml
+++ b/backend/src/pythonbrasil/site/configure.zcml
@@ -11,13 +11,17 @@
file="permissions.zcml"
/>
+
-
+
+
+
+
diff --git a/backend/src/pythonbrasil/site/content/sponsors/sponsor.py b/backend/src/pythonbrasil/site/content/sponsors/sponsor.py
index 70153ff..b51899b 100644
--- a/backend/src/pythonbrasil/site/content/sponsors/sponsor.py
+++ b/backend/src/pythonbrasil/site/content/sponsors/sponsor.py
@@ -1,6 +1,5 @@
from Acquisition import aq_parent
from plone.app.dexterity.textindexer import searchable
-from plone.app.multilingual.dx import directives as ml_directives
from plone.app.textfield import RichText as RichTextField
from plone.app.z3cform.widgets.richtext import RichTextFieldWidget
from plone.autoform import directives
@@ -27,7 +26,6 @@ class ISponsor(Interface):
)
directives.order_before(description="*")
directives.order_before(title="*")
- ml_directives.languageindependent("title")
text = RichTextField(
title=_("label_text", default="Text"),
description="",
diff --git a/backend/src/pythonbrasil/site/controlpanel/configure.zcml b/backend/src/pythonbrasil/site/controlpanel/configure.zcml
index 70601d7..64722d4 100644
--- a/backend/src/pythonbrasil/site/controlpanel/configure.zcml
+++ b/backend/src/pythonbrasil/site/controlpanel/configure.zcml
@@ -5,4 +5,6 @@
i18n_domain="pythonbrasil.site"
>
+
+
diff --git a/backend/src/pythonbrasil/site/dependencies.zcml b/backend/src/pythonbrasil/site/dependencies.zcml
index 9d7b261..fe1dc14 100644
--- a/backend/src/pythonbrasil/site/dependencies.zcml
+++ b/backend/src/pythonbrasil/site/dependencies.zcml
@@ -3,4 +3,6 @@
+
+
diff --git a/backend/src/pythonbrasil/site/indexers/configure.zcml b/backend/src/pythonbrasil/site/indexers/configure.zcml
index bad8247..ee4ad7c 100644
--- a/backend/src/pythonbrasil/site/indexers/configure.zcml
+++ b/backend/src/pythonbrasil/site/indexers/configure.zcml
@@ -2,4 +2,6 @@
+
+
diff --git a/backend/src/pythonbrasil/site/locales/update.py b/backend/src/pythonbrasil/site/locales/__main__.py
similarity index 61%
rename from backend/src/pythonbrasil/site/locales/update.py
rename to backend/src/pythonbrasil/site/locales/__main__.py
index 462f82c..a5677b6 100644
--- a/backend/src/pythonbrasil/site/locales/update.py
+++ b/backend/src/pythonbrasil/site/locales/__main__.py
@@ -12,14 +12,12 @@
PATTERN = r"^[a-z]{2}.*"
-domains = ("pythonbrasil.site",)
-cwd = Path.cwd()
-target_path = Path(__file__).parent.parent.resolve()
-locale_path = target_path / "locales"
-i18ndude = cwd / "bin" / "i18ndude"
-if not i18ndude.exists():
- i18ndude = cwd / "i18ndude"
+locale_path = Path(__file__).parent.resolve()
+target_path = locale_path.parent.resolve()
+domains = [path.name[:-4] for path in locale_path.glob("*.pot")]
+
+i18ndude = "uvx i18ndude"
# ignore node_modules files resulting in errors
excludes = '"*.html *json-schema*.xml"'
@@ -39,10 +37,7 @@ def locale_folder_setup(domain: str):
f"--input={locale_path}/{domain}.pot "
f"--output={locale_path}/{lang}/LC_MESSAGES/{domain}.po"
)
- subprocess.call(
- cmd,
- shell=True,
- )
+ subprocess.call(cmd, shell=True) # noQA: S602
def _rebuild(domain: str):
@@ -51,10 +46,7 @@ def _rebuild(domain: str):
f"--exclude {excludes} "
f"--create {domain} {target_path}"
)
- subprocess.call(
- cmd,
- shell=True,
- )
+ subprocess.call(cmd, shell=True) # noQA: S602
def _sync(domain: str):
@@ -62,18 +54,16 @@ def _sync(domain: str):
f"{i18ndude} sync --pot {locale_path}/{domain}.pot "
f"{locale_path}/*/LC_MESSAGES/{domain}.po"
)
- subprocess.call(
- cmd,
- shell=True,
- )
+ subprocess.call(cmd, shell=True) # noQA: S602
+
+
+def main():
+ for domain in domains:
+ logger.info(f"Updating translations for {domain}")
+ locale_folder_setup(domain)
+ _rebuild(domain)
+ _sync(domain)
-def update_locale():
- if i18ndude.exists():
- for domain in domains:
- logger.info(f"Updating translations for {domain}")
- locale_folder_setup(domain)
- _rebuild(domain)
- _sync(domain)
- else:
- logger.error("Not able to find i18ndude")
+if __name__ == "__main__":
+ main()
diff --git a/backend/src/pythonbrasil/site/locales/en/LC_MESSAGES/pythonbrasil.site.po b/backend/src/pythonbrasil/site/locales/en/LC_MESSAGES/pythonbrasil.site.po
index fb7f062..4b59d98 100644
--- a/backend/src/pythonbrasil/site/locales/en/LC_MESSAGES/pythonbrasil.site.po
+++ b/backend/src/pythonbrasil/site/locales/en/LC_MESSAGES/pythonbrasil.site.po
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2022-05-25 17:12+0000\n"
+"POT-Creation-Date: 2025-04-29 19:33+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -13,3 +13,75 @@ msgstr ""
"Language-Name: English\n"
"Preferred-Encodings: utf-8 latin1\n"
"Domain: pythonbrasil.site\n"
+
+#: pythonbrasil/site/profiles/default/types/Sponsor.xml
+msgid "Conference Sponsor."
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorsDB.xml
+msgid "Conference Sponsoring information."
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:22
+msgid "Create example content to showcase the new website"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:21
+msgid "Display on Frontpage"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorLevel.xml
+msgid "Package of sponsorship for the conference."
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:13
+msgid "Package to configure a new PythonBrasil 2025 site"
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:22
+msgid "PythonBrasil 2025: Example content"
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:13
+msgid "PythonBrasil 2025: Install"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:22
+msgid "Should this level be displayed on the FrontPage?"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/Sponsor.xml
+msgid "Sponsor"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorsDB.xml
+msgid "Sponsors Database"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorLevel.xml
+msgid "Sponsorship Level"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:14
+msgid "Visibility"
+msgstr ""
+
+#. Default: "Used in item listings and search results."
+#: pythonbrasil/site/content/sponsors/sponsor.py:21
+msgid "help_description"
+msgstr ""
+
+#. Default: "Summary"
+#: pythonbrasil/site/content/sponsors/sponsor.py:20
+msgid "label_description"
+msgstr ""
+
+#. Default: "Text"
+#: pythonbrasil/site/content/sponsors/sponsor.py:30
+msgid "label_text"
+msgstr ""
+
+#. Default: "Title"
+#: pythonbrasil/site/content/sponsors/sponsor.py:17
+msgid "label_title"
+msgstr ""
diff --git a/backend/src/pythonbrasil/site/locales/pt_BR/LC_MESSAGES/pythonbrasil.site.po b/backend/src/pythonbrasil/site/locales/pt_BR/LC_MESSAGES/pythonbrasil.site.po
index 6abbf1a..fb7561b 100644
--- a/backend/src/pythonbrasil/site/locales/pt_BR/LC_MESSAGES/pythonbrasil.site.po
+++ b/backend/src/pythonbrasil/site/locales/pt_BR/LC_MESSAGES/pythonbrasil.site.po
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2022-05-25 17:12+0000\n"
+"POT-Creation-Date: 2025-04-29 19:33+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -13,3 +13,75 @@ msgstr ""
"Language-Name: English\n"
"Preferred-Encodings: utf-8 latin1\n"
"Domain: DOMAIN\n"
+
+#: pythonbrasil/site/profiles/default/types/Sponsor.xml
+msgid "Conference Sponsor."
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorsDB.xml
+msgid "Conference Sponsoring information."
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:22
+msgid "Create example content to showcase the new website"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:21
+msgid "Display on Frontpage"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorLevel.xml
+msgid "Package of sponsorship for the conference."
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:13
+msgid "Package to configure a new PythonBrasil 2025 site"
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:22
+msgid "PythonBrasil 2025: Example content"
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:13
+msgid "PythonBrasil 2025: Install"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:22
+msgid "Should this level be displayed on the FrontPage?"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/Sponsor.xml
+msgid "Sponsor"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorsDB.xml
+msgid "Sponsors Database"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorLevel.xml
+msgid "Sponsorship Level"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:14
+msgid "Visibility"
+msgstr ""
+
+#. Default: "Used in item listings and search results."
+#: pythonbrasil/site/content/sponsors/sponsor.py:21
+msgid "help_description"
+msgstr ""
+
+#. Default: "Summary"
+#: pythonbrasil/site/content/sponsors/sponsor.py:20
+msgid "label_description"
+msgstr ""
+
+#. Default: "Text"
+#: pythonbrasil/site/content/sponsors/sponsor.py:30
+msgid "label_text"
+msgstr ""
+
+#. Default: "Title"
+#: pythonbrasil/site/content/sponsors/sponsor.py:17
+msgid "label_title"
+msgstr ""
diff --git a/backend/src/pythonbrasil/site/locales/pythonbrasil.site.pot b/backend/src/pythonbrasil/site/locales/pythonbrasil.site.pot
index 6189082..d07a202 100644
--- a/backend/src/pythonbrasil/site/locales/pythonbrasil.site.pot
+++ b/backend/src/pythonbrasil/site/locales/pythonbrasil.site.pot
@@ -4,7 +4,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2022-05-25 17:12+0000\n"
+"POT-Creation-Date: 2025-04-29 19:33+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -16,3 +16,75 @@ msgstr ""
"Language-Name: English\n"
"Preferred-Encodings: utf-8 latin1\n"
"Domain: pythonbrasil.site\n"
+
+#: pythonbrasil/site/profiles/default/types/Sponsor.xml
+msgid "Conference Sponsor."
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorsDB.xml
+msgid "Conference Sponsoring information."
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:22
+msgid "Create example content to showcase the new website"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:21
+msgid "Display on Frontpage"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorLevel.xml
+msgid "Package of sponsorship for the conference."
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:13
+msgid "Package to configure a new PythonBrasil 2025 site"
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:22
+msgid "PythonBrasil 2025: Example content"
+msgstr ""
+
+#: pythonbrasil/site/profiles.zcml:13
+msgid "PythonBrasil 2025: Install"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:22
+msgid "Should this level be displayed on the FrontPage?"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/Sponsor.xml
+msgid "Sponsor"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorsDB.xml
+msgid "Sponsors Database"
+msgstr ""
+
+#: pythonbrasil/site/profiles/default/types/SponsorLevel.xml
+msgid "Sponsorship Level"
+msgstr ""
+
+#: pythonbrasil/site/content/sponsors/sponsor_level.py:14
+msgid "Visibility"
+msgstr ""
+
+#. Default: "Used in item listings and search results."
+#: pythonbrasil/site/content/sponsors/sponsor.py:21
+msgid "help_description"
+msgstr ""
+
+#. Default: "Summary"
+#: pythonbrasil/site/content/sponsors/sponsor.py:20
+msgid "label_description"
+msgstr ""
+
+#. Default: "Text"
+#: pythonbrasil/site/content/sponsors/sponsor.py:30
+msgid "label_text"
+msgstr ""
+
+#. Default: "Title"
+#: pythonbrasil/site/content/sponsors/sponsor.py:17
+msgid "label_title"
+msgstr ""
diff --git a/backend/src/pythonbrasil/site/profiles.zcml b/backend/src/pythonbrasil/site/profiles.zcml
index 2c2cb92..48ac997 100644
--- a/backend/src/pythonbrasil/site/profiles.zcml
+++ b/backend/src/pythonbrasil/site/profiles.zcml
@@ -21,14 +21,6 @@
pre_handler=".setuphandlers.initial.create_example_content"
/>
-
-
False
-
diff --git a/backend/src/pythonbrasil/site/profiles/default/controlpanel.xml b/backend/src/pythonbrasil/site/profiles/default/controlpanel.xml
index a75d00c..75eae58 100644
--- a/backend/src/pythonbrasil/site/profiles/default/controlpanel.xml
+++ b/backend/src/pythonbrasil/site/profiles/default/controlpanel.xml
@@ -1,4 +1,6 @@
+
+
diff --git a/backend/src/pythonbrasil/site/profiles/default/metadata.xml b/backend/src/pythonbrasil/site/profiles/default/metadata.xml
index ce4c8d9..bcd4155 100644
--- a/backend/src/pythonbrasil/site/profiles/default/metadata.xml
+++ b/backend/src/pythonbrasil/site/profiles/default/metadata.xml
@@ -1,10 +1,11 @@
- 1000
+ 20250425001
- profile-plone.app.contenttypes:default
profile-plone.volto:default
profile-plone.app.caching:default
profile-plone.app.caching:with-caching-proxy
+ profile-collective.volto.formsupport:default
+ profile-plonegovbr.socialmedia:default
diff --git a/backend/src/pythonbrasil/site/profiles/default/registry/main.xml b/backend/src/pythonbrasil/site/profiles/default/registry/main.xml
new file mode 100644
index 0000000..fe15ad8
--- /dev/null
+++ b/backend/src/pythonbrasil/site/profiles/default/registry/main.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/backend/src/pythonbrasil/site/profiles/default/types/Plone_Site.xml b/backend/src/pythonbrasil/site/profiles/default/types/Plone_Site.xml
new file mode 100644
index 0000000..905e5ac
--- /dev/null
+++ b/backend/src/pythonbrasil/site/profiles/default/types/Plone_Site.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/src/pythonbrasil/site/profiles/default/userschema.xml b/backend/src/pythonbrasil/site/profiles/default/userschema.xml
deleted file mode 100644
index f591057..0000000
--- a/backend/src/pythonbrasil/site/profiles/default/userschema.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- Portrait URL
-
- False
- Portrait URL
-
-
-
diff --git a/backend/src/pythonbrasil/site/profiles/oauth/metadata.xml b/backend/src/pythonbrasil/site/profiles/oauth/metadata.xml
deleted file mode 100644
index f4308ca..0000000
--- a/backend/src/pythonbrasil/site/profiles/oauth/metadata.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- 20241020001
-
- profile-pas.plugins.authomatic:default
-
-
diff --git a/backend/src/pythonbrasil/site/profiles/oauth/registry/pas.plugins.authomatic.interfaces.IPasPluginsAuthomaticSettings.xml b/backend/src/pythonbrasil/site/profiles/oauth/registry/pas.plugins.authomatic.interfaces.IPasPluginsAuthomaticSettings.xml
deleted file mode 100644
index 3a3886a..0000000
--- a/backend/src/pythonbrasil/site/profiles/oauth/registry/pas.plugins.authomatic.interfaces.IPasPluginsAuthomaticSettings.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
- {
- "github": {
- "id": 1,
- "display": {
- "title": "Github",
- "cssclasses": {
- "button": "plone-btn plone-btn-default",
- "icon": "glypicon glyphicon-github"
- },
- "as_form": false
- },
- "propertymap": {
- "email": "email",
- "link": "home_page",
- "location": "location",
- "name": "fullname",
- "avatar_url": "portrait",
- "username": "github_username"
- },
- "class_": "authomatic.providers.oauth2.GitHub",
- "consumer_key": "Ov23liNwUaBP8X5mLhmE",
- "consumer_secret": "3d0769620ff58655dc1f4c6d16ce522161a413fb",
- "access_headers": {
- "User-Agent": "Plone (pas.plugins.authomatic)"
- }
- }
-}
- F3CyxO60ZE
- username
-
-
diff --git a/backend/src/pythonbrasil/site/profiles/uninstall/browserlayer.xml b/backend/src/pythonbrasil/site/profiles/uninstall/browserlayer.xml
deleted file mode 100644
index 048ed08..0000000
--- a/backend/src/pythonbrasil/site/profiles/uninstall/browserlayer.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/03e3d75a791d4fa98378626ba8f62d07/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/03e3d75a791d4fa98378626ba8f62d07/data.json
index 2e3628e..d7e5ca6 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/03e3d75a791d4fa98378626ba8f62d07/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/03e3d75a791d4fa98378626ba8f62d07/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "main.png",
"image": {
"blob_path": "03e3d75a791d4fa98378626ba8f62d07/image/main.png",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2024-10-19T20:26:17+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/0d05308db57c450da4ae80e8a3c47ece/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/0d05308db57c450da4ae80e8a3c47ece/data.json
index eae9df3..b82a99a 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/0d05308db57c450da4ae80e8a3c47ece/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/0d05308db57c450da4ae80e8a3c47ece/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "logo-slim.svg",
"image": {
"blob_path": "0d05308db57c450da4ae80e8a3c47ece/image/logo-slim.svg",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2024-10-19T17:23:08+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/1e6a267195ba41459ce3a869ac4714f6/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/1e6a267195ba41459ce3a869ac4714f6/data.json
index 8eb9b91..b62676b 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/1e6a267195ba41459ce3a869ac4714f6/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/1e6a267195ba41459ce3a869ac4714f6/data.json
@@ -33,6 +33,7 @@
"f485daa6-93dc-4e6e-ad16-baa34042887a"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-30T21:29:57+00:00",
"creators": [
@@ -44,7 +45,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "edicoes-anteriores",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -54,19 +54,6 @@
"stealable": true
},
"modified": "2025-01-30T21:29:57+00:00",
- "parent": {
- "@id": "/evento",
- "@type": "Document",
- "Subject": [],
- "UID": "81bb6aa3c33644c296ffbc767b8c05c7",
- "description": "Conhe\u00e7a a PythonBrasil, o maior evento da Am\u00e9rica Latina sobre a linguagem Python e suas aplica\u00e7\u00f5es",
- "effective": "2025-01-30T21:38:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "O Evento",
- "type_title": "Page"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "private",
@@ -75,6 +62,7 @@
"title": "Edi\u00e7\u00f5es Anteriores",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/24689ede20f346c09ce7d50b68ff893b/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/24689ede20f346c09ce7d50b68ff893b/data.json
index 500a557..314d866 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/24689ede20f346c09ce7d50b68ff893b/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/24689ede20f346c09ce7d50b68ff893b/data.json
@@ -91,18 +91,18 @@
"9ebd0467-ee7d-4849-a7c9-63a135634db5"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-30T21:19:49+00:00",
"creators": [
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629"
],
"description": "Tire suas d\u00favidas sobre a Python Brasil 2025",
- "effective": "2025-01-30T21:38:07",
+ "effective": "2025-01-30T21:38:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "perguntas-frequentes",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -112,19 +112,6 @@
"stealable": true
},
"modified": "2025-01-30T23:12:12+00:00",
- "parent": {
- "@id": "/evento",
- "@type": "Document",
- "Subject": [],
- "UID": "81bb6aa3c33644c296ffbc767b8c05c7",
- "description": "Conhe\u00e7a a PythonBrasil, o maior evento da Am\u00e9rica Latina sobre a linguagem Python e suas aplica\u00e7\u00f5es",
- "effective": "2025-01-30T21:38:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "O Evento",
- "type_title": "Page"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -133,6 +120,7 @@
"title": "Perguntas Frequentes",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/28be0c28818647be98201618302a142c/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/28be0c28818647be98201618302a142c/data.json
index 34465a7..b58228c 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/28be0c28818647be98201618302a142c/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/28be0c28818647be98201618302a142c/data.json
@@ -33,7 +33,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "diamante",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -41,19 +40,6 @@
"lock": {},
"modified": "2025-01-30T21:54:34+00:00",
"nav_title": null,
- "parent": {
- "@id": "/patrocine",
- "@type": "SponsorsDB",
- "Subject": [],
- "UID": "818ea1c0827944c394330a1c3d658866",
- "description": "Sua organiza\u00e7\u00e3o pode ser parte do maior evento de Python do Brasil",
- "effective": "2025-01-30T23:00:43+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Patrocine",
- "type_title": "Sponsors Database"
- },
"preview_caption": null,
"preview_image": {
"blob_path": "28be0c28818647be98201618302a142c/preview_image/diamante.png",
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/2f992ae440894d7191a24d75d669de4a/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/2f992ae440894d7191a24d75d669de4a/data.json
index 8fa6db8..dbfce55 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/2f992ae440894d7191a24d75d669de4a/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/2f992ae440894d7191a24d75d669de4a/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "logo.svg",
"image": {
"blob_path": "2f992ae440894d7191a24d75d669de4a/image/logo.svg",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2024-10-19T17:23:08+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/52e0e3e2d1564eca97eb22eae2fbebbf/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/52e0e3e2d1564eca97eb22eae2fbebbf/data.json
index ad5a541..91ad707 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/52e0e3e2d1564eca97eb22eae2fbebbf/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/52e0e3e2d1564eca97eb22eae2fbebbf/data.json
@@ -191,18 +191,18 @@
"e1ddaec1-f262-492c-87d6-6e2c6431b20e"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-22T22:08:35+00:00",
"creators": [
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629"
],
"description": "Todos os participantes, instrutores e organizadores da confer\u00eancia concordam em cumprir o C\u00f3digo de Conduta da PythonBrasil.",
- "effective": "2025-01-30T21:37:54",
+ "effective": "2025-01-30T21:37:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "codigo-de-conduta",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -212,19 +212,6 @@
"stealable": true
},
"modified": "2025-01-30T21:37:54+00:00",
- "parent": {
- "@id": "/evento",
- "@type": "Document",
- "Subject": [],
- "UID": "81bb6aa3c33644c296ffbc767b8c05c7",
- "description": "Conhe\u00e7a a PythonBrasil, o maior evento da Am\u00e9rica Latina sobre a linguagem Python e suas aplica\u00e7\u00f5es",
- "effective": "2025-01-30T21:38:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "O Evento",
- "type_title": "Page"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -233,6 +220,7 @@
"title": "C\u00f3digo de Conduta",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/573e6d9f0eca43b3a8b838c29a1c0053/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/573e6d9f0eca43b3a8b838c29a1c0053/data.json
index 6ed481d..6a2c21e 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/573e6d9f0eca43b3a8b838c29a1c0053/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/573e6d9f0eca43b3a8b838c29a1c0053/data.json
@@ -45,7 +45,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "bronze",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -53,19 +52,6 @@
"lock": {},
"modified": "2025-01-30T21:55:13+00:00",
"nav_title": null,
- "parent": {
- "@id": "/patrocine",
- "@type": "SponsorsDB",
- "Subject": [],
- "UID": "818ea1c0827944c394330a1c3d658866",
- "description": "Sua organiza\u00e7\u00e3o pode ser parte do maior evento de Python do Brasil",
- "effective": "2025-01-30T23:00:43+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Patrocine",
- "type_title": "Sponsors Database"
- },
"preview_caption": null,
"preview_image": {
"blob_path": "573e6d9f0eca43b3a8b838c29a1c0053/preview_image/bronze.png",
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/64ae8a06559f4255b20152220da6fba3/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/64ae8a06559f4255b20152220da6fba3/data.json
index 6173439..f788965 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/64ae8a06559f4255b20152220da6fba3/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/64ae8a06559f4255b20152220da6fba3/data.json
@@ -22,6 +22,7 @@
"67313966-fd37-4969-8aa2-676101eba01a"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-30T21:16:20+00:00",
"creators": [
@@ -33,7 +34,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "ingressos",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -43,14 +43,6 @@
"stealable": true
},
"modified": "2025-01-30T21:16:20+00:00",
- "parent": {
- "@id": "/",
- "@type": "Plone Site",
- "UID": "plone_site_root",
- "description": "Encontro da comunidade Python brasileira, entre 21 a 27 de Outubro, em S\u00e3o Paulo, SP",
- "title": "PythonBrasil 2025",
- "type_title": "Plone Site"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "private",
@@ -59,6 +51,7 @@
"title": "Ingressos",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/6fef01c46be34684bb42ac0e4d990a2f/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/6fef01c46be34684bb42ac0e4d990a2f/data.json
index 9b61132..1d867fc 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/6fef01c46be34684bb42ac0e4d990a2f/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/6fef01c46be34684bb42ac0e4d990a2f/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "pybr2022-plateia.jpg",
"image": {
"blob_path": "6fef01c46be34684bb42ac0e4d990a2f/image/pybr2022-plateia.jpg",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2025-01-31T20:37:59+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/76b343b1ca41450db2728865ca5d459b/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/76b343b1ca41450db2728865ca5d459b/data.json
index e4ef27c..a49026b 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/76b343b1ca41450db2728865ca5d459b/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/76b343b1ca41450db2728865ca5d459b/data.json
@@ -33,7 +33,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "prata",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -41,19 +40,6 @@
"lock": {},
"modified": "2025-01-30T21:55:01+00:00",
"nav_title": null,
- "parent": {
- "@id": "/patrocine",
- "@type": "SponsorsDB",
- "Subject": [],
- "UID": "818ea1c0827944c394330a1c3d658866",
- "description": "Sua organiza\u00e7\u00e3o pode ser parte do maior evento de Python do Brasil",
- "effective": "2025-01-30T23:00:43+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Patrocine",
- "type_title": "Sponsors Database"
- },
"preview_caption": null,
"preview_image": {
"blob_path": "76b343b1ca41450db2728865ca5d459b/preview_image/prata.png",
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/8077308bcd7c43f88a5055932ec3cc6b/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/8077308bcd7c43f88a5055932ec3cc6b/data.json
index 70a7922..fddbf10 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/8077308bcd7c43f88a5055932ec3cc6b/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/8077308bcd7c43f88a5055932ec3cc6b/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "logo-splash.png",
"image": {
"blob_path": "8077308bcd7c43f88a5055932ec3cc6b/image/logo-splash.png",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2025-01-30T21:17:48+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/818ea1c0827944c394330a1c3d658866/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/818ea1c0827944c394330a1c3d658866/data.json
index fe05f8b..8e2ee5a 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/818ea1c0827944c394330a1c3d658866/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/818ea1c0827944c394330a1c3d658866/data.json
@@ -53,12 +53,11 @@
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629"
],
"description": "Sua organiza\u00e7\u00e3o pode ser parte do maior evento de Python do Brasil",
- "effective": "2025-01-30T23:00:43",
+ "effective": "2025-01-30T23:00:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "patrocine",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -66,14 +65,6 @@
"lock": {},
"modified": "2025-01-30T23:02:29+00:00",
"nav_title": null,
- "parent": {
- "@id": "/",
- "@type": "Plone Site",
- "UID": "plone_site_root",
- "description": "Encontro da comunidade Python brasileira, entre 21 a 27 de Outubro, em S\u00e3o Paulo, SP",
- "title": "PythonBrasil 2025",
- "type_title": "Plone Site"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/81bb6aa3c33644c296ffbc767b8c05c7/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/81bb6aa3c33644c296ffbc767b8c05c7/data.json
index f29f6b6..dc2df7c 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/81bb6aa3c33644c296ffbc767b8c05c7/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/81bb6aa3c33644c296ffbc767b8c05c7/data.json
@@ -33,18 +33,18 @@
"c1c311fe-eef9-4b6b-9e48-7187d88428b3"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-22T22:06:17+00:00",
"creators": [
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629"
],
"description": "Conhe\u00e7a a PythonBrasil, o maior evento da Am\u00e9rica Latina sobre a linguagem Python e suas aplica\u00e7\u00f5es",
- "effective": "2025-01-30T21:38:00",
+ "effective": "2025-01-30T21:38:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "evento",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -54,14 +54,6 @@
"stealable": true
},
"modified": "2025-01-30T22:49:04+00:00",
- "parent": {
- "@id": "/",
- "@type": "Plone Site",
- "UID": "plone_site_root",
- "description": "Encontro da comunidade Python brasileira, entre 21 a 27 de Outubro, em S\u00e3o Paulo, SP",
- "title": "PythonBrasil 2025",
- "type_title": "Plone Site"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -70,6 +62,7 @@
"title": "O Evento",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/96fdfa7c97784194b9f4cd0f0819e7f1/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/96fdfa7c97784194b9f4cd0f0819e7f1/data.json
index c236b5c..8628d29 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/96fdfa7c97784194b9f4cd0f0819e7f1/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/96fdfa7c97784194b9f4cd0f0819e7f1/data.json
@@ -33,7 +33,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "platina",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -41,19 +40,6 @@
"lock": {},
"modified": "2025-01-30T21:52:07+00:00",
"nav_title": null,
- "parent": {
- "@id": "/patrocine",
- "@type": "SponsorsDB",
- "Subject": [],
- "UID": "818ea1c0827944c394330a1c3d658866",
- "description": "Sua organiza\u00e7\u00e3o pode ser parte do maior evento de Python do Brasil",
- "effective": "2025-01-30T23:00:43+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Patrocine",
- "type_title": "Sponsors Database"
- },
"preview_caption": null,
"preview_image": {
"blob_path": "96fdfa7c97784194b9f4cd0f0819e7f1/preview_image/platina.png",
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/__metadata__.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/__metadata__.json
index 2dabc03..d2948e7 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/__metadata__.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/__metadata__.json
@@ -1,19 +1,19 @@
{
"__version__": "1.0.0",
"_blob_files_": [
+ "fa4f3a56ff634ab7a5ebb1f106126dfd/file/2025-pythonbrasil-patrocinio.pdf",
+ "0d05308db57c450da4ae80e8a3c47ece/image/logo-slim.svg",
"8077308bcd7c43f88a5055932ec3cc6b/image/logo-splash.png",
- "573e6d9f0eca43b3a8b838c29a1c0053/preview_image/bronze.png",
+ "2f992ae440894d7191a24d75d669de4a/image/logo.svg",
+ "03e3d75a791d4fa98378626ba8f62d07/image/main.png",
"6fef01c46be34684bb42ac0e4d990a2f/image/pybr2022-plateia.jpg",
+ "c630576df3264cb0ad7799d28f52a393/image/pybr2022-treinamento.jpg",
+ "c2d0e0645016413f9e5d719b628fb72d/image/pybr2024.jpg",
+ "573e6d9f0eca43b3a8b838c29a1c0053/preview_image/bronze.png",
"28be0c28818647be98201618302a142c/preview_image/diamante.png",
- "96fdfa7c97784194b9f4cd0f0819e7f1/preview_image/platina.png",
"f9db2eccb58a4e9eb32b43708a0ebc0a/preview_image/ouro.png",
- "76b343b1ca41450db2728865ca5d459b/preview_image/prata.png",
- "fa4f3a56ff634ab7a5ebb1f106126dfd/file/2025-pythonbrasil-patrocinio.pdf",
- "c2d0e0645016413f9e5d719b628fb72d/image/pybr2024.jpg",
- "c630576df3264cb0ad7799d28f52a393/image/pybr2022-treinamento.jpg",
- "0d05308db57c450da4ae80e8a3c47ece/image/logo-slim.svg",
- "2f992ae440894d7191a24d75d669de4a/image/logo.svg",
- "03e3d75a791d4fa98378626ba8f62d07/image/main.png"
+ "96fdfa7c97784194b9f4cd0f0819e7f1/preview_image/platina.png",
+ "76b343b1ca41450db2728865ca5d459b/preview_image/prata.png"
],
"_data_files_": [
"plone_site_root/data.json",
@@ -151,6 +151,9 @@
},
"1e6a267195ba41459ce3a869ac4714f6": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -158,6 +161,9 @@
},
"24689ede20f346c09ce7d50b68ff893b": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -165,6 +171,9 @@
},
"28be0c28818647be98201618302a142c": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -179,6 +188,9 @@
},
"52e0e3e2d1564eca97eb22eae2fbebbf": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -186,6 +198,9 @@
},
"573e6d9f0eca43b3a8b838c29a1c0053": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -193,6 +208,9 @@
},
"64ae8a06559f4255b20152220da6fba3": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -200,6 +218,9 @@
},
"6fef01c46be34684bb42ac0e4d990a2f": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -207,6 +228,9 @@
},
"76b343b1ca41450db2728865ca5d459b": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -214,6 +238,9 @@
},
"8077308bcd7c43f88a5055932ec3cc6b": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -221,6 +248,9 @@
},
"818ea1c0827944c394330a1c3d658866": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -228,6 +258,9 @@
},
"81bb6aa3c33644c296ffbc767b8c05c7": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -235,6 +268,9 @@
},
"96fdfa7c97784194b9f4cd0f0819e7f1": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -249,6 +285,9 @@
},
"aba03e63fe93484685256445d8e4f646": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"be1f8aa4-b6c8-48ef-8d37-aa4fd88a4095": [
"Owner"
]
@@ -256,6 +295,9 @@
},
"b1279249bca341d78e0762bc2a12094f": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"be1f8aa4-b6c8-48ef-8d37-aa4fd88a4095": [
"Owner"
]
@@ -263,6 +305,9 @@
},
"c2d0e0645016413f9e5d719b628fb72d": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -270,6 +315,9 @@
},
"c630576df3264cb0ad7799d28f52a393": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -277,6 +325,9 @@
},
"f17ec2cb79cf4a75896ce3a6b5bc8f54": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -284,6 +335,9 @@
},
"f9db2eccb58a4e9eb32b43708a0ebc0a": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -291,6 +345,9 @@
},
"fa4f3a56ff634ab7a5ebb1f106126dfd": {
"local_roles": {
+ "admin": [
+ "Owner"
+ ],
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629": [
"Owner"
]
@@ -313,21 +370,21 @@
"2f992ae440894d7191a24d75d669de4a": 1,
"52e0e3e2d1564eca97eb22eae2fbebbf": 1,
"573e6d9f0eca43b3a8b838c29a1c0053": 4,
- "64ae8a06559f4255b20152220da6fba3": 45,
+ "64ae8a06559f4255b20152220da6fba3": 44,
"6fef01c46be34684bb42ac0e4d990a2f": 5,
"76b343b1ca41450db2728865ca5d459b": 3,
"8077308bcd7c43f88a5055932ec3cc6b": 3,
- "818ea1c0827944c394330a1c3d658866": 46,
+ "818ea1c0827944c394330a1c3d658866": 45,
"81bb6aa3c33644c296ffbc767b8c05c7": 43,
"96fdfa7c97784194b9f4cd0f0819e7f1": 1,
- "a720393b3c0240e5bd27c43fcd2cfd1e": 42,
+ "a720393b3c0240e5bd27c43fcd2cfd1e": 41,
"aba03e63fe93484685256445d8e4f646": 4,
- "b1279249bca341d78e0762bc2a12094f": 44,
+ "b1279249bca341d78e0762bc2a12094f": 42,
"c2d0e0645016413f9e5d719b628fb72d": 4,
"c630576df3264cb0ad7799d28f52a393": 6,
"f17ec2cb79cf4a75896ce3a6b5bc8f54": 0,
"f9db2eccb58a4e9eb32b43708a0ebc0a": 2,
- "fa4f3a56ff634ab7a5ebb1f106126dfd": 47
+ "fa4f3a56ff634ab7a5ebb1f106126dfd": 46
},
"relations": []
}
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/a720393b3c0240e5bd27c43fcd2cfd1e/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/a720393b3c0240e5bd27c43fcd2cfd1e/data.json
index 32b6d9d..01c817f 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/a720393b3c0240e5bd27c43fcd2cfd1e/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/a720393b3c0240e5bd27c43fcd2cfd1e/data.json
@@ -38,6 +38,7 @@
"ecfe183b-1d44-48f9-8eac-5de33884c7f5"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2024-05-27T03:23:26+00:00",
"creators": [
@@ -49,7 +50,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "images",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -59,14 +59,6 @@
"stealable": true
},
"modified": "2025-01-31T20:38:00+00:00",
- "parent": {
- "@id": "/",
- "@type": "Plone Site",
- "UID": "plone_site_root",
- "description": "Encontro da comunidade Python brasileira, entre 21 a 27 de Outubro, em S\u00e3o Paulo, SP",
- "title": "PythonBrasil 2025",
- "type_title": "Plone Site"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -75,6 +67,7 @@
"title": "Imagens",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/aba03e63fe93484685256445d8e4f646/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/aba03e63fe93484685256445d8e4f646/data.json
index 8e66e28..c5e99af 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/aba03e63fe93484685256445d8e4f646/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/aba03e63fe93484685256445d8e4f646/data.json
@@ -145,18 +145,18 @@
"9c85c775-df7f-4e18-83c5-8517473bf39c"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-30T22:49:04+00:00",
"creators": [
"be1f8aa4-b6c8-48ef-8d37-aa4fd88a4095"
],
"description": "",
- "effective": "2025-01-31T22:14:17",
+ "effective": "2025-01-31T22:14:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "prevencao-a-covid-19",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -166,19 +166,6 @@
"stealable": true
},
"modified": "2025-01-31T22:14:17+00:00",
- "parent": {
- "@id": "/evento",
- "@type": "Document",
- "Subject": [],
- "UID": "81bb6aa3c33644c296ffbc767b8c05c7",
- "description": "Conhe\u00e7a a PythonBrasil, o maior evento da Am\u00e9rica Latina sobre a linguagem Python e suas aplica\u00e7\u00f5es",
- "effective": "2025-01-30T21:38:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "O Evento",
- "type_title": "Page"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -187,6 +174,7 @@
"title": "Preven\u00e7\u00e3o a Covid 19",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/b1279249bca341d78e0762bc2a12094f/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/b1279249bca341d78e0762bc2a12094f/data.json
index 274c1ef..54351d8 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/b1279249bca341d78e0762bc2a12094f/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/b1279249bca341d78e0762bc2a12094f/data.json
@@ -71,18 +71,18 @@
"a660d1a8-033c-4a67-8dca-42007fa5e148"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-22T22:14:02+00:00",
"creators": [
"be1f8aa4-b6c8-48ef-8d37-aa4fd88a4095"
],
"description": "De 21 a 27 de outubro de 2025",
- "effective": "2025-01-30T22:12:11",
+ "effective": "2025-01-30T22:12:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "agenda",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -92,14 +92,6 @@
"stealable": true
},
"modified": "2025-01-30T22:29:57+00:00",
- "parent": {
- "@id": "/",
- "@type": "Plone Site",
- "UID": "plone_site_root",
- "description": "Encontro da comunidade Python brasileira, entre 21 a 27 de Outubro, em S\u00e3o Paulo, SP",
- "title": "PythonBrasil 2025",
- "type_title": "Plone Site"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -108,6 +100,7 @@
"title": "Agenda",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c2d0e0645016413f9e5d719b628fb72d/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c2d0e0645016413f9e5d719b628fb72d/data.json
index 58008fc..64419ec 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c2d0e0645016413f9e5d719b628fb72d/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c2d0e0645016413f9e5d719b628fb72d/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "pybr2024.jpg",
"image": {
"blob_path": "c2d0e0645016413f9e5d719b628fb72d/image/pybr2024.jpg",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2025-01-31T20:37:59+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c630576df3264cb0ad7799d28f52a393/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c630576df3264cb0ad7799d28f52a393/data.json
index 163d461..b819542 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c630576df3264cb0ad7799d28f52a393/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/c630576df3264cb0ad7799d28f52a393/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "pybr2022-treinamento.jpg",
"image": {
"blob_path": "c630576df3264cb0ad7799d28f52a393/image/pybr2022-treinamento.jpg",
@@ -29,19 +28,6 @@
"layout": "image_view",
"lock": {},
"modified": "2025-01-31T20:38:00+00:00",
- "parent": {
- "@id": "/images",
- "@type": "Document",
- "Subject": [],
- "UID": "a720393b3c0240e5bd27c43fcd2cfd1e",
- "description": "Site images",
- "effective": "1969-12-31T00:00:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Imagens",
- "type_title": "Page"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f17ec2cb79cf4a75896ce3a6b5bc8f54/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f17ec2cb79cf4a75896ce3a6b5bc8f54/data.json
index d033228..118b0dd 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f17ec2cb79cf4a75896ce3a6b5bc8f54/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f17ec2cb79cf4a75896ce3a6b5bc8f54/data.json
@@ -82,18 +82,18 @@
"282c0238-48c4-4eaf-b604-693db49a68a8"
]
},
+ "changeNote": "",
"contributors": [],
"created": "2025-01-30T21:28:40+00:00",
"creators": [
"e9ba8889-9bb3-4d41-9b0f-6c5dfbca6629"
],
"description": "Entre em contato com a organiza\u00e7\u00e3o da Python Brasil 2025",
- "effective": "2025-01-30T21:38:54",
+ "effective": "2025-01-30T21:38:00+00:00",
"exclude_from_nav": false,
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "contato",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -103,19 +103,6 @@
"stealable": true
},
"modified": "2025-01-30T21:44:13+00:00",
- "parent": {
- "@id": "/evento",
- "@type": "Document",
- "Subject": [],
- "UID": "81bb6aa3c33644c296ffbc767b8c05c7",
- "description": "Conhe\u00e7a a PythonBrasil, o maior evento da Am\u00e9rica Latina sobre a linguagem Python e suas aplica\u00e7\u00f5es",
- "effective": "2025-01-30T21:38:00+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "O Evento",
- "type_title": "Page"
- },
"preview_caption": null,
"preview_image": null,
"review_state": "published",
@@ -124,6 +111,7 @@
"title": "Fale Conosco",
"type_title": "Page",
"version": "current",
+ "versioning_enabled": true,
"workflow_history": {
"simple_publication_workflow": [
{
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f9db2eccb58a4e9eb32b43708a0ebc0a/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f9db2eccb58a4e9eb32b43708a0ebc0a/data.json
index 12fb2a8..af7bf55 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f9db2eccb58a4e9eb32b43708a0ebc0a/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/f9db2eccb58a4e9eb32b43708a0ebc0a/data.json
@@ -33,7 +33,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"id": "ouro",
"is_folderish": true,
"language": "##DEFAULT##",
@@ -41,19 +40,6 @@
"lock": {},
"modified": "2025-01-30T21:54:49+00:00",
"nav_title": null,
- "parent": {
- "@id": "/patrocine",
- "@type": "SponsorsDB",
- "Subject": [],
- "UID": "818ea1c0827944c394330a1c3d658866",
- "description": "Sua organiza\u00e7\u00e3o pode ser parte do maior evento de Python do Brasil",
- "effective": "2025-01-30T23:00:43+00:00",
- "image_field": null,
- "image_scales": {},
- "review_state": "published",
- "title": "Patrocine",
- "type_title": "Sponsors Database"
- },
"preview_caption": null,
"preview_image": {
"blob_path": "f9db2eccb58a4e9eb32b43708a0ebc0a/preview_image/ouro.png",
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/fa4f3a56ff634ab7a5ebb1f106126dfd/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/fa4f3a56ff634ab7a5ebb1f106126dfd/data.json
index f2980e2..57204e3 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/fa4f3a56ff634ab7a5ebb1f106126dfd/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/fa4f3a56ff634ab7a5ebb1f106126dfd/data.json
@@ -14,7 +14,6 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
"file": {
"blob_path": "fa4f3a56ff634ab7a5ebb1f106126dfd/file/2025-pythonbrasil-patrocinio.pdf",
"content-type": "application/pdf",
@@ -27,14 +26,6 @@
"layout": "file_view",
"lock": {},
"modified": "2025-01-13T12:24:08+00:00",
- "parent": {
- "@id": "/",
- "@type": "Plone Site",
- "UID": "plone_site_root",
- "description": "Encontro da comunidade Python brasileira, entre 21 a 27 de Outubro, em S\u00e3o Paulo, SP",
- "title": "PythonBrasil 2025",
- "type_title": "Plone Site"
- },
"review_state": null,
"rights": "",
"subjects": [],
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/plone_site_root/data.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/plone_site_root/data.json
index 09baffe..705d3ff 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/plone_site_root/data.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/content/plone_site_root/data.json
@@ -17,9 +17,8 @@
}
],
"label": "Submeta sua proposta",
- "styles": {
- "backgroundColor": "grey"
- },
+ "styles": {},
+ "theme": "default",
"title": "Submiss\u00e3o de atividades"
},
"af098dc9-9fc6-4600-b40f-161a88513807": {
@@ -32,9 +31,7 @@
}
],
"label": "Garanta seu Ingresso",
- "styles": {
- "backgroundColor": "grey"
- },
+ "styles": {},
"title": "Ingressos \u00e0 venda"
}
},
@@ -45,9 +42,8 @@
]
},
"headline": "Fa\u00e7a Parte",
- "styles": {
- "backgroundColor": "mainColor"
- }
+ "styles": {},
+ "theme": "red"
},
"345e2281-cedc-44c2-9aa3-600a885d1bb0": {
"@type": "gridBlock",
@@ -62,9 +58,8 @@
}
],
"label": "Plano de Patroc\u00ednio",
- "styles": {
- "backgroundColor": "grey"
- },
+ "styles": {},
+ "theme": "grey",
"title": "Patrocine"
}
},
@@ -74,22 +69,24 @@
]
},
"headline": "Patrocine",
- "styles": {
- "backgroundColor": "transparent"
- }
+ "styles": {},
+ "theme": "default"
},
"42165e4a-c5c1-4229-8161-00f96b0deab0": {
"@type": "image",
- "align": "full",
+ "align": "center",
"alt": "Logotipo da PythonBrasil 2025, com a palavra Python em vermelho, Brasil e 2025 em branco. Texto, em letras brancas, S\u00e3o Paulo, SP, 21 a 27 de Outubro",
"credit": {},
"description": "",
"image_field": "image",
"size": "l",
"styles": {
- "backgroundColor": "grey",
+ "blockWidth:noprefix": {
+ "--block-width": "100%"
+ },
"size:noprefix": "large"
},
+ "theme": "grey",
"title": "main.png",
"url": "resolveuid/03e3d75a791d4fa98378626ba8f62d07"
}
@@ -111,7 +108,49 @@
"expires": null,
"exportimport.constrains": {},
"exportimport.conversation": [],
- "exportimport.versions": {},
+ "facebook_app_id": "",
+ "facebook_username": "",
+ "footer_links": [
+ {
+ "@id": "60e04d84-fc3c-4dee-b548-73099515a1af",
+ "href": [
+ {
+ "@id": "resolveuid/f17ec2cb79cf4a75896ce3a6b5bc8f54",
+ "@type": "Document",
+ "Description": "Entre em contato com a organiza\u00e7\u00e3o da Python Brasil 2025",
+ "Title": "Fale Conosco",
+ "title": "Fale Conosco"
+ }
+ ],
+ "title": "Fale Conosco"
+ },
+ {
+ "@id": "bb7628e1-dba5-44e2-aef0-c7f4dbf7804b",
+ "href": [
+ {
+ "@id": "resolveuid/24689ede20f346c09ce7d50b68ff893b",
+ "@type": "Document",
+ "Description": "Tire suas d\u00favidas sobre a Python Brasil 2025",
+ "Title": "Perguntas Frequentes",
+ "title": "Perguntas Frequentes"
+ }
+ ],
+ "title": "Perguntas Frequentes"
+ },
+ {
+ "@id": "72160063-6d39-42a0-a03c-0dc0621d5bf7",
+ "href": [
+ {
+ "@id": "resolveuid/52e0e3e2d1564eca97eb22eae2fbebbf",
+ "@type": "Document",
+ "Description": "Todos os participantes, instrutores e organizadores da confer\u00eancia concordam em cumprir o C\u00f3digo de Conduta da PythonBrasil.",
+ "Title": "C\u00f3digo de Conduta",
+ "title": "C\u00f3digo de Conduta"
+ }
+ ],
+ "title": "C\u00f3digo de Conduta"
+ }
+ ],
"id": "Plone",
"is_folderish": true,
"items_total": 5,
@@ -120,12 +159,83 @@
"locked": false,
"stealable": true
},
- "parent": {},
+ "preview_caption_link": null,
"review_state": null,
"rights": "",
+ "share_social_data": true,
+ "social_links": [
+ {
+ "@id": "c67e5d80-1744-43f0-9bd8-4f58511194ad",
+ "href": [
+ {
+ "@id": "https://pynews.com.br/@pythonbrasil",
+ "title": "Mastodon"
+ }
+ ],
+ "id": "mastodon",
+ "title": "Mastodon"
+ },
+ {
+ "@id": "444ef18c-b773-43ea-8594-131e6d35a645",
+ "href": [
+ {
+ "@id": "https://x.com/pythonbrasil/",
+ "title": "X"
+ }
+ ],
+ "id": "x",
+ "title": "X"
+ },
+ {
+ "@id": "2fc33af3-8aa5-4e94-a783-845a5add2ded",
+ "href": [
+ {
+ "@id": "https://instagram.com/pythonbrasil/",
+ "title": "Instagram"
+ }
+ ],
+ "id": "instagram",
+ "title": "Instagram"
+ },
+ {
+ "@id": "5889d02c-a6a1-43e0-9799-b17e899843fc",
+ "href": [
+ {
+ "@id": "https://bsky.app/profile/pythonbrasil.bsky.social",
+ "title": "BlueSky"
+ }
+ ],
+ "id": "bluesky",
+ "title": "BlueSky"
+ },
+ {
+ "@id": "360468f5-d9a3-41f1-a2c6-e66a79aebda9",
+ "href": [
+ {
+ "@id": "https://www.linkedin.com/company/apyb/",
+ "title": "LinkedIn APyB"
+ }
+ ],
+ "id": "linkedin",
+ "title": "LinkedIn APyB"
+ },
+ {
+ "@id": "b91a5edc-c0bc-4907-98a5-4e57dd45a154",
+ "href": [
+ {
+ "@id": "https://www.youtube.com/c/pythonbrasiloficial",
+ "title": "YouTube"
+ }
+ ],
+ "id": "youtube",
+ "title": "YouTube"
+ }
+ ],
"subjects": [],
- "table_of_contents": null,
"title": "PythonBrasil 2025",
"type_title": "Plone Site",
- "workflow_history": {}
+ "workflow_history": {},
+ "working_copy": null,
+ "working_copy_of": null,
+ "x_username": ""
}
diff --git a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/relations.json b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/relations.json
index fe51488..96d3fbc 100644
--- a/backend/src/pythonbrasil/site/setuphandlers/examplecontent/relations.json
+++ b/backend/src/pythonbrasil/site/setuphandlers/examplecontent/relations.json
@@ -1 +1,7 @@
-[]
+[
+ {
+ "from_attribute": "isReferencing",
+ "from_uuid": "3f772cc1b1104023b2a7865f89a1f5be",
+ "to_uuid": "03e3d75a791d4fa98378626ba8f62d07"
+ }
+]
diff --git a/backend/src/pythonbrasil/site/testing.py b/backend/src/pythonbrasil/site/testing.py
index 9390c5e..8b2d664 100644
--- a/backend/src/pythonbrasil/site/testing.py
+++ b/backend/src/pythonbrasil/site/testing.py
@@ -6,7 +6,7 @@
from plone.app.testing import PloneSandboxLayer
from plone.testing.zope import WSGI_SERVER_FIXTURE
-import pythonbrasil.site # noQA
+import pythonbrasil.site
class Layer(PloneSandboxLayer):
diff --git a/backend/src/pythonbrasil/site/upgrades/configure.zcml b/backend/src/pythonbrasil/site/upgrades/configure.zcml
index bc19993..4b65075 100644
--- a/backend/src/pythonbrasil/site/upgrades/configure.zcml
+++ b/backend/src/pythonbrasil/site/upgrades/configure.zcml
@@ -3,17 +3,8 @@
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
>
-
+
+
+
diff --git a/backend/src/pythonbrasil/site/upgrades/v20250425001/__init__.py b/backend/src/pythonbrasil/site/upgrades/v20250425001/__init__.py
new file mode 100644
index 0000000..d2171fe
--- /dev/null
+++ b/backend/src/pythonbrasil/site/upgrades/v20250425001/__init__.py
@@ -0,0 +1,115 @@
+from plone import api
+from Products.GenericSetup.tool import SetupTool
+from pythonbrasil.site import logger
+from uuid import uuid4
+
+
+REDES = [
+ {
+ "@id": f"{uuid4()}",
+ "id": "mastodon",
+ "title": "Mastodon",
+ "href": [{"@id": "https://pynews.com.br/@pythonbrasil", "title": "Mastodon"}],
+ },
+ {
+ "@id": f"{uuid4()}",
+ "id": "x",
+ "title": "X",
+ "href": [{"@id": "https://x.com/pythonbrasil/", "title": "X"}],
+ },
+ {
+ "@id": f"{uuid4()}",
+ "id": "instagram",
+ "title": "Instagram",
+ "href": [{"@id": "https://instagram.com/pythonbrasil/", "title": "Instagram"}],
+ },
+ {
+ "@id": f"{uuid4()}",
+ "id": "bluesky",
+ "title": "BlueSky",
+ "href": [
+ {
+ "@id": "https://bsky.app/profile/pythonbrasil.bsky.social",
+ "title": "BlueSky",
+ }
+ ],
+ },
+ {
+ "@id": f"{uuid4()}",
+ "id": "linkedin",
+ "title": "LinkedIn APyB",
+ "href": [
+ {"@id": "https://www.linkedin.com/company/apyb/", "title": "LinkedIn APyB"}
+ ],
+ },
+ {
+ "@id": f"{uuid4()}",
+ "id": "youtube",
+ "title": "YouTube",
+ "href": [
+ {"@id": "https://www.youtube.com/c/pythonbrasiloficial", "title": "YouTube"}
+ ],
+ },
+]
+
+LINKS = [
+ {
+ "@id": "60e04d84-fc3c-4dee-b548-73099515a1af",
+ "href": [
+ {
+ "@id": "resolveuid/f17ec2cb79cf4a75896ce3a6b5bc8f54",
+ "@type": "Document",
+ "Title": "Fale Conosco",
+ "title": "Fale Conosco",
+ }
+ ],
+ "title": "Fale Conosco",
+ },
+ {
+ "@id": "bb7628e1-dba5-44e2-aef0-c7f4dbf7804b",
+ "href": [
+ {
+ "@id": "resolveuid/24689ede20f346c09ce7d50b68ff893b",
+ "@type": "Document",
+ "Title": "Perguntas Frequentes",
+ "title": "Perguntas Frequentes",
+ }
+ ],
+ "title": "Perguntas Frequentes",
+ },
+ {
+ "@id": "72160063-6d39-42a0-a03c-0dc0621d5bf7",
+ "href": [
+ {
+ "@id": "resolveuid/52e0e3e2d1564eca97eb22eae2fbebbf",
+ "@type": "Document",
+ "Title": "Código de Conduta",
+ "title": "Código de Conduta",
+ }
+ ],
+ "title": "Código de Conduta",
+ },
+]
+
+
+def instala_dependencias(setup_tool: SetupTool):
+ """Instala plonegovbr.socialmedia."""
+ profile = "default"
+ for package in ("plonegovbr.socialmedia", "collective.volto.formsupport"):
+ profile_id = f"profile-{package}:{profile}"
+ setup_tool.runAllImportStepsFromProfile(profile_id)
+ logger.info(f"Instalado complemento {package}")
+
+
+def configura_redes_sociais(setup_tool: SetupTool):
+ """Configura as redes sociais que usaremos."""
+ portal = api.portal.get()
+ portal.social_links = REDES
+ logger.info("Adicionadas as redes sociais")
+
+
+def configura_links(setup_tool: SetupTool):
+ """Configura links de rodapé."""
+ portal = api.portal.get()
+ portal.footer_links = LINKS
+ logger.info("Adicionados os links de rodapé")
diff --git a/backend/src/pythonbrasil/site/upgrades/v20250425001/configure.zcml b/backend/src/pythonbrasil/site/upgrades/v20250425001/configure.zcml
new file mode 100644
index 0000000..d0a41cb
--- /dev/null
+++ b/backend/src/pythonbrasil/site/upgrades/v20250425001/configure.zcml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/src/pythonbrasil/site/utils.py b/backend/src/pythonbrasil/site/utils.py
index a5cfb46..906bd75 100644
--- a/backend/src/pythonbrasil/site/utils.py
+++ b/backend/src/pythonbrasil/site/utils.py
@@ -15,6 +15,6 @@ def sponsor_levels(context):
level_title = brain.Title
level_url = brain.getURL()
# HACK
- display_frontpage = False if level_id in ("supporting", "oss") else True
+ display_frontpage = level_id not in ("supporting", "oss")
items.append((level_id, level_title, level_url, display_frontpage))
return items
diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py
index 3a3fc58..a4cc37d 100644
--- a/backend/tests/conftest.py
+++ b/backend/tests/conftest.py
@@ -8,11 +8,9 @@
globals().update(
- fixtures_factory(
- (
- (ACCEPTANCE_TESTING, "acceptance"),
- (FUNCTIONAL_TESTING, "functional"),
- (INTEGRATION_TESTING, "integration"),
- )
- )
+ fixtures_factory((
+ (ACCEPTANCE_TESTING, "acceptance"),
+ (FUNCTIONAL_TESTING, "functional"),
+ (INTEGRATION_TESTING, "integration"),
+ ))
)
diff --git a/backend/tests/setup/test_setup_install.py b/backend/tests/setup/test_setup_install.py
index d771bcd..4ec9b3b 100644
--- a/backend/tests/setup/test_setup_install.py
+++ b/backend/tests/setup/test_setup_install.py
@@ -14,4 +14,4 @@ def test_browserlayer(self, browser_layers):
def test_latest_version(self, profile_last_version):
"""Test latest version of default profile."""
- assert profile_last_version(f"{PACKAGE_NAME}:default") == "1000"
+ assert profile_last_version(f"{PACKAGE_NAME}:default") == "20250425001"
diff --git a/backend/tests/setup/test_setup_uninstall.py b/backend/tests/setup/test_setup_uninstall.py
deleted file mode 100644
index bded6e0..0000000
--- a/backend/tests/setup/test_setup_uninstall.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from pythonbrasil.site import PACKAGE_NAME
-
-import pytest
-
-
-class TestSetupUninstall:
- @pytest.fixture(autouse=True)
- def uninstalled(self, installer):
- installer.uninstall_product(PACKAGE_NAME)
-
- def test_addon_uninstalled(self, installer):
- """Test if pythonbrasil.site is uninstalled."""
- assert installer.is_product_installed(PACKAGE_NAME) is False
-
- def test_browserlayer_not_registered(self, browser_layers):
- """Test that IBrowserLayer is not registered."""
- from pythonbrasil.site.interfaces import IBrowserLayer
-
- assert IBrowserLayer not in browser_layers
diff --git a/backend/tox.ini b/backend/tox.ini
deleted file mode 100644
index 0348414..0000000
--- a/backend/tox.ini
+++ /dev/null
@@ -1,212 +0,0 @@
-# Generated from:
-# https://github.com/plone/meta/tree/master/config/default
-# See the inline comments on how to expand/tweak this configuration file
-[tox]
-# We need 4.4.0 for constrain_package_deps.
-min_version = 4.4.0
-envlist =
- lint
- test
- dependencies
-
-
-##
-# Add extra configuration options in .meta.toml:
-# [tox]
-# envlist_lines = """
-# my_other_environment
-# """
-# config_lines = """
-# my_extra_top_level_tox_configuration_lines
-# """
-##
-
-[testenv]
-skip_install = true
-allowlist_externals =
- echo
- false
-# Make sure typos like `tox -e formaat` are caught instead of silently doing nothing.
-# See https://github.com/tox-dev/tox/issues/2858.
-commands =
- echo "Unrecognized environment name {envname}"
- false
-
-[testenv:init]
-description = Prepare environment
-skip_install = true
-deps =
- mxdev
-commands =
- mxdev -c mx.ini
- echo "Initial setup for mxdev"
-
-
-[testenv:format]
-description = automatically reformat code
-skip_install = true
-deps =
- pre-commit
-commands =
- pre-commit run -a pyupgrade
- pre-commit run -a isort
- pre-commit run -a black
- pre-commit run -a zpretty
-
-[testenv:lint]
-description = run linters that will help improve the code style
-skip_install = true
-deps =
- pre-commit
-commands =
- # Run pre-commit without chdir to the root of the git repository
- python -c "from pre_commit import main; main._adjust_args_and_chdir = lambda args: None; raise SystemExit(main.main())" run -a
-
-[testenv:dependencies]
-description = check if the package defines all its dependencies
-skip_install = true
-deps =
- build
- z3c.dependencychecker==2.11
-commands =
- python -m build --sdist --no-isolation
- dependencychecker
-
-[testenv:dependencies-graph]
-description = generate a graph out of the dependencies of the package
-skip_install = false
-allowlist_externals =
- sh
-deps =
- pipdeptree==2.5.1
- graphviz # optional dependency of pipdeptree
-commands =
- sh -c 'pipdeptree --exclude setuptools,wheel,pipdeptree,zope.interface,zope.component --graph-output svg > dependencies.svg'
-
-[testenv:test]
-description = run the distribution tests
-use_develop = true
-skip_install = false
-constrain_package_deps = true
-set_env =
- ROBOT_BROWSER=headlesschrome
-
-##
-# Specify extra test environment variables in .meta.toml:
-# [tox]
-# test_environment_variables = """
-# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/
-# """
-#
-# Set constrain_package_deps .meta.toml:
-# [tox]
-# constrain_package_deps = false
-##
-deps =
- pytest-plone
- pytest
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
-
-##
-# Specify additional deps in .meta.toml:
-# [tox]
-# test_deps_additional = """
-# -esources/plonegovbr.portal_base[test]
-# """
-#
-# Specify a custom constraints file in .meta.toml:
-# [tox]
-# constraints_file = "https://my-server.com/constraints.txt"
-##
-commands =
- pytest --disable-warnings {posargs} {toxinidir}/tests
-extras =
- test
-
-
-[testenv:coverage]
-description = get a test coverage report
-use_develop = true
-skip_install = false
-constrain_package_deps = true
-set_env =
- ROBOT_BROWSER=headlesschrome
-
-##
-# Specify extra test environment variables in .meta.toml:
-# [tox]
-# test_environment_variables = """
-# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/
-# """
-#
-# Set constrain_package_deps .meta.toml:
-# [tox]
-# constrain_package_deps = "false"
-##
-deps =
- pytest-plone
- pytest
- coverage
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
-
-commands =
- coverage run --source pythonbrasil.site -m pytest {posargs} --disable-warnings {toxinidir}/tests
- coverage report -m --format markdown
- coverage xml
-extras =
- test
-
-
-[testenv:release-check]
-description = ensure that the distribution is ready to release
-skip_install = true
-deps =
- twine
- build
- towncrier
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
-
-commands =
- # fake version to not have to install the package
- # we build the change log as news entries might break
- # the README that is displayed on PyPI
- towncrier build --version=100.0.0 --yes
- python -m build --sdist --no-isolation
- twine check dist/*
-
-[testenv:circular]
-description = ensure there are no cyclic dependencies
-use_develop = true
-skip_install = false
-set_env =
-
-##
-# Specify extra test environment variables in .meta.toml:
-# [tox]
-# test_environment_variables = """
-# PIP_EXTRA_INDEX_URL=https://my-pypi.my-server.com/
-# """
-##
-allowlist_externals =
- sh
-deps =
- pipdeptree
- pipforester
- -c https://dist.plone.org/release/6.0-dev/constraints.txt
-
-commands =
- # Generate the full dependency tree
- sh -c 'pipdeptree -j > forest.json'
- # Generate a DOT graph with the circular dependencies, if any
- pipforester -i forest.json -o forest.dot --cycles
- # Report if there are any circular dependencies, i.e. error if there are any
- pipforester -i forest.json --check-cycles -o /dev/null
-
-
-##
-# Add extra configuration options in .meta.toml:
-# [tox]
-# extra_lines = """
-# _your own configuration lines_
-# """
-##
diff --git a/backend/uv.lock b/backend/uv.lock
new file mode 100644
index 0000000..76e5691
--- /dev/null
+++ b/backend/uv.lock
@@ -0,0 +1,6361 @@
+version = 1
+revision = 1
+requires-python = ">=3.12"
+resolution-markers = [
+ "python_full_version >= '3.13' and platform_python_implementation == 'CPython'",
+ "python_full_version < '3.13' and platform_python_implementation == 'CPython'",
+ "python_full_version >= '3.13' and platform_python_implementation != 'CPython'",
+ "python_full_version < '3.13' and platform_python_implementation != 'CPython'",
+]
+
+[manifest]
+constraints = [
+ { name = "accesscontrol", specifier = "==7.2" },
+ { name = "acquisition", specifier = "==6.1" },
+ { name = "alabaster", marker = "python_full_version == '3.9.*'", specifier = "==0.7.14" },
+ { name = "alabaster", marker = "python_full_version >= '3.10'", specifier = "==1.0.0" },
+ { name = "argcomplete", specifier = "==3.5.2" },
+ { name = "argh", specifier = "==0.31.3" },
+ { name = "async-generator", specifier = "==1.10" },
+ { name = "attrs", specifier = "==24.2.0" },
+ { name = "authencoding", specifier = "==6.0" },
+ { name = "babel", specifier = "==2.16.0" },
+ { name = "backports-cached-property", specifier = "==1.0.2" },
+ { name = "backports-tarfile", specifier = "==1.2.0" },
+ { name = "beautifulsoup4", specifier = "==4.12.3" },
+ { name = "bleach", specifier = "==6.2.0" },
+ { name = "borg-localrole", specifier = "==3.1.11" },
+ { name = "btrees", specifier = "==6.1" },
+ { name = "build", specifier = "==1.2.2.post1" },
+ { name = "cachecontrol", specifier = "==0.14.1" },
+ { name = "cached-property", specifier = "==2.0.1" },
+ { name = "certifi", specifier = "==2024.12.14" },
+ { name = "cffi", specifier = "==1.17.1" },
+ { name = "chameleon", specifier = "==4.4.4" },
+ { name = "charset-normalizer", specifier = "==3.4.1" },
+ { name = "check-manifest", specifier = "==0.50" },
+ { name = "click", specifier = "==8.1.7" },
+ { name = "click-default-group", specifier = "==1.2.4" },
+ { name = "cmarkgfm", specifier = "==2024.11.20" },
+ { name = "collective-mockmailhost", specifier = "==3.0.0" },
+ { name = "collective-monkeypatcher", specifier = "==2.0.0" },
+ { name = "collective-recipe-omelette", specifier = "==2.0.0" },
+ { name = "collective-recipe-template", specifier = "==2.2" },
+ { name = "collective-recipe-vscode", specifier = "==0.1.9" },
+ { name = "collective-xmltestreport", specifier = "==2.0.2" },
+ { name = "collective-z3cform-datagridfield", specifier = "==3.0.3" },
+ { name = "colorama", specifier = "==0.4.6" },
+ { name = "commonmark", specifier = "==0.9.1" },
+ { name = "configparser", specifier = "==7.1.0" },
+ { name = "coverage", specifier = "==7.6.9" },
+ { name = "cryptography", specifier = "==44.0.0" },
+ { name = "cssselect", specifier = "==1.2.0" },
+ { name = "datetime", specifier = "==5.5" },
+ { name = "decorator", specifier = "==5.1.1" },
+ { name = "deprecated", specifier = "==1.2.15" },
+ { name = "diazo", specifier = "==2.0.3" },
+ { name = "distro", specifier = "==1.9.0" },
+ { name = "documenttemplate", specifier = "==4.6" },
+ { name = "docutils", marker = "python_full_version == '3.9.*'", specifier = "==0.20.1" },
+ { name = "docutils", marker = "python_full_version >= '3.10'", specifier = "==0.21.2" },
+ { name = "exceptiongroup", specifier = "==1.2.2" },
+ { name = "extensionclass", specifier = "==6.0" },
+ { name = "fancycompleter", specifier = "==0.9.1" },
+ { name = "feedparser", specifier = "==6.0.11" },
+ { name = "filelock", specifier = "==3.16.1" },
+ { name = "five-customerize", specifier = "==3.0.0" },
+ { name = "five-intid", specifier = "==2.0.1" },
+ { name = "five-localsitemanager", specifier = "==4.0" },
+ { name = "furl", specifier = "==2.1.3" },
+ { name = "furo", specifier = "==2024.8.6" },
+ { name = "future", specifier = "==1.0.0" },
+ { name = "gitdb", specifier = "==4.0.11" },
+ { name = "gitpython", specifier = "==3.1.43" },
+ { name = "gunicorn", specifier = "==23.0.0" },
+ { name = "h11", specifier = "==0.14.0" },
+ { name = "horse-with-no-namespace", specifier = ">=20250408.0" },
+ { name = "httplib2", specifier = "==0.22.0" },
+ { name = "i18ndude", specifier = "==6.2.1" },
+ { name = "icalendar", specifier = "==6.1.1" },
+ { name = "idna", specifier = "==3.10" },
+ { name = "imagesize", specifier = "==1.4.1" },
+ { name = "importlib-metadata", specifier = "==8.5.0" },
+ { name = "importlib-resources", specifier = "==6.4.5" },
+ { name = "incremental", specifier = "==24.7.2" },
+ { name = "iniconfig", specifier = "==2.0.0" },
+ { name = "jaraco-classes", specifier = "==3.4.0" },
+ { name = "jaraco-context", specifier = "==6.0.1" },
+ { name = "jaraco-functools", specifier = "==4.1.0" },
+ { name = "jeepney", specifier = "==0.8.0" },
+ { name = "jinja2", specifier = "==3.1.5" },
+ { name = "jsonschema", specifier = "==4.23.0" },
+ { name = "jsonschema-specifications", specifier = "==2024.10.1" },
+ { name = "keyring", specifier = "==25.5.0" },
+ { name = "legacy-cgi", specifier = "==2.6.2" },
+ { name = "lockfile", specifier = "==0.12.2" },
+ { name = "lxml", specifier = "==5.3.0" },
+ { name = "lxml-html-clean", specifier = "==0.4.1" },
+ { name = "manuel", specifier = "==1.13.0" },
+ { name = "markdown", specifier = "==3.7" },
+ { name = "markdown-it-py", specifier = "==3.0.0" },
+ { name = "markupsafe", specifier = "==3.0.2" },
+ { name = "mdurl", specifier = "==0.1.2" },
+ { name = "missing", specifier = "==5.0" },
+ { name = "mock", specifier = "==5.1.0" },
+ { name = "more-itertools", specifier = "==10.5.0" },
+ { name = "mr-developer", specifier = "==2.0.2" },
+ { name = "msgpack", specifier = "==1.1.0" },
+ { name = "multimapping", specifier = "==5.0" },
+ { name = "multipart", specifier = "==1.2.1" },
+ { name = "mxdev", specifier = "==4.0.3" },
+ { name = "mypy", specifier = ">=1.15.0" },
+ { name = "natsort", specifier = "==8.4.0" },
+ { name = "nh3", specifier = "==0.2.19" },
+ { name = "nt-svcutils", specifier = "==2.13.0" },
+ { name = "oauthlib", specifier = "==3.2.2" },
+ { name = "orderedmultidict", specifier = "==1.0.1" },
+ { name = "outcome", specifier = "==1.3.0.post0" },
+ { name = "overrides", specifier = "==7.7.0" },
+ { name = "packaging", specifier = "==24.2" },
+ { name = "paste", specifier = "==3.10.1" },
+ { name = "pastedeploy", specifier = "==3.1.0" },
+ { name = "pdbpp", specifier = "==0.10.3" },
+ { name = "pep440", specifier = "==0.1.2" },
+ { name = "pep517", specifier = "==0.13.1" },
+ { name = "persistence", specifier = "==5.1" },
+ { name = "persistent", specifier = "==6.1" },
+ { name = "piexif", specifier = "==1.1.3" },
+ { name = "pillow", specifier = "==11.0.0" },
+ { name = "pip", specifier = "==25.0.1" },
+ { name = "pkginfo", specifier = "==1.10.0" },
+ { name = "plone", specifier = "==6.1.1" },
+ { name = "plone-alterego", specifier = "==2.0.1" },
+ { name = "plone-api", specifier = "==2.5.0" },
+ { name = "plone-app-blocks", specifier = "==7.0.1" },
+ { name = "plone-app-caching", specifier = "==4.1.0" },
+ { name = "plone-app-content", specifier = "==4.1.9" },
+ { name = "plone-app-contentlisting", specifier = "==3.0.5" },
+ { name = "plone-app-contentmenu", specifier = "==3.0.7" },
+ { name = "plone-app-contentrules", specifier = "==5.0.6" },
+ { name = "plone-app-contenttypes", specifier = "==4.0.5" },
+ { name = "plone-app-customerize", specifier = "==2.0.2" },
+ { name = "plone-app-debugtoolbar", specifier = "==1.4.0" },
+ { name = "plone-app-dexterity", specifier = "==4.0.4" },
+ { name = "plone-app-discussion", specifier = "==5.0.0" },
+ { name = "plone-app-drafts", specifier = "==2.0.0" },
+ { name = "plone-app-event", specifier = "==5.2.1" },
+ { name = "plone-app-i18n", specifier = "==4.0.1" },
+ { name = "plone-app-intid", specifier = "==2.0.0" },
+ { name = "plone-app-iterate", specifier = "==6.1.0" },
+ { name = "plone-app-jquerytools", specifier = "==1.9.5" },
+ { name = "plone-app-layout", specifier = "==5.0.2" },
+ { name = "plone-app-linkintegrity", specifier = "==4.0.6" },
+ { name = "plone-app-locales", specifier = "==6.0.30" },
+ { name = "plone-app-lockingbehavior", specifier = "==2.0.2" },
+ { name = "plone-app-mosaic", specifier = "==3.2.1" },
+ { name = "plone-app-multilingual", specifier = "==8.2.3" },
+ { name = "plone-app-portlets", specifier = "==6.0.1" },
+ { name = "plone-app-querystring", specifier = "==2.1.3" },
+ { name = "plone-app-redirector", specifier = "==3.0.4" },
+ { name = "plone-app-registry", specifier = "==2.0.6" },
+ { name = "plone-app-relationfield", specifier = "==4.0.2" },
+ { name = "plone-app-robotframework", specifier = "==2.1.5" },
+ { name = "plone-app-standardtiles", specifier = "==3.2.1" },
+ { name = "plone-app-testing", specifier = "==7.1.1" },
+ { name = "plone-app-textfield", specifier = "==3.0.0" },
+ { name = "plone-app-theming", specifier = "==5.0.12" },
+ { name = "plone-app-tiles", specifier = "==4.0.1" },
+ { name = "plone-app-upgrade", specifier = "==3.2.0" },
+ { name = "plone-app-users", specifier = "==3.1.1" },
+ { name = "plone-app-uuid", specifier = "==2.2.3" },
+ { name = "plone-app-versioningbehavior", specifier = "==2.0.4" },
+ { name = "plone-app-viewletmanager", specifier = "==4.0.4" },
+ { name = "plone-app-vocabularies", specifier = "==6.0.2" },
+ { name = "plone-app-widgets", specifier = "==5.0.2" },
+ { name = "plone-app-workflow", specifier = "==5.0.4" },
+ { name = "plone-app-z3cform", specifier = "==4.7.4" },
+ { name = "plone-autoform", specifier = "==2.0.3" },
+ { name = "plone-autoinclude", specifier = "==2.0.3" },
+ { name = "plone-base", specifier = "==2.0.3" },
+ { name = "plone-batching", specifier = "==2.0.6" },
+ { name = "plone-behavior", specifier = "==2.0.1" },
+ { name = "plone-browserlayer", specifier = "==3.0.2" },
+ { name = "plone-cachepurging", specifier = "==3.0.2" },
+ { name = "plone-caching", specifier = "==2.0.1" },
+ { name = "plone-classicui", specifier = "==1.0.0" },
+ { name = "plone-contentrules", specifier = "==3.0.1" },
+ { name = "plone-dexterity", specifier = "==3.0.7" },
+ { name = "plone-distribution", specifier = "==3.1.1" },
+ { name = "plone-event", specifier = "==2.0.2" },
+ { name = "plone-exportimport", specifier = "==1.1.0" },
+ { name = "plone-folder", specifier = "==4.0.1" },
+ { name = "plone-formwidget-autocomplete", specifier = "==1.4.1" },
+ { name = "plone-formwidget-namedfile", specifier = "==3.1.1" },
+ { name = "plone-formwidget-recurrence", specifier = "==3.0.5" },
+ { name = "plone-i18n", specifier = "==5.1.0" },
+ { name = "plone-indexer", specifier = "==2.0.1" },
+ { name = "plone-intelligenttext", specifier = "==4.0.1" },
+ { name = "plone-jsonserializer", specifier = "==0.9.11" },
+ { name = "plone-keyring", specifier = "==4.0.2" },
+ { name = "plone-locking", specifier = "==3.0.2" },
+ { name = "plone-memoize", specifier = "==3.0.3" },
+ { name = "plone-namedfile", specifier = "==7.0.1" },
+ { name = "plone-outputfilters", specifier = "==5.0.4" },
+ { name = "plone-portlet-collection", specifier = "==4.0.4" },
+ { name = "plone-portlet-static", specifier = "==4.0.4" },
+ { name = "plone-portlets", specifier = "==3.0.2" },
+ { name = "plone-protect", specifier = "==5.0.3" },
+ { name = "plone-recipe-command", specifier = "==1.1" },
+ { name = "plone-recipe-zeoserver", specifier = "==3.0.4" },
+ { name = "plone-recipe-zope2instance", specifier = "==8.0.0" },
+ { name = "plone-registry", specifier = "==2.0.1" },
+ { name = "plone-releaser", specifier = "==2.4.1" },
+ { name = "plone-reload", specifier = "==4.0.0" },
+ { name = "plone-resource", specifier = "==3.0.2" },
+ { name = "plone-resourceeditor", specifier = "==4.0.1" },
+ { name = "plone-rest", specifier = "==5.0.0" },
+ { name = "plone-restapi", specifier = "==9.13.3" },
+ { name = "plone-rfc822", specifier = "==3.0.1" },
+ { name = "plone-scale", specifier = "==4.1.4" },
+ { name = "plone-schema", specifier = "==2.0.2" },
+ { name = "plone-schemaeditor", specifier = "==4.0.11" },
+ { name = "plone-session", specifier = "==4.0.4" },
+ { name = "plone-staticresources", specifier = "==2.2.5" },
+ { name = "plone-stringinterp", specifier = "==2.0.2" },
+ { name = "plone-subrequest", specifier = "==2.0.5" },
+ { name = "plone-supermodel", specifier = "==2.0.4" },
+ { name = "plone-testing", specifier = "==9.0.5" },
+ { name = "plone-theme", specifier = "==4.0.3" },
+ { name = "plone-tiles", specifier = "==2.3.1" },
+ { name = "plone-transformchain", specifier = "==3.0.1" },
+ { name = "plone-uuid", specifier = "==2.0.1" },
+ { name = "plone-versioncheck", specifier = "==1.8.2" },
+ { name = "plone-volto", specifier = "==5.0.4" },
+ { name = "plone-z3cform", specifier = "==2.0.4" },
+ { name = "plonegovbr-socialmedia", specifier = "==2.0.0a5" },
+ { name = "plonetheme-barceloneta", specifier = "==3.2.3" },
+ { name = "pluggy", specifier = "==1.5.0" },
+ { name = "products-btreefolder2", specifier = "==5.1" },
+ { name = "products-cmfcore", specifier = "==3.7" },
+ { name = "products-cmfdifftool", specifier = "==4.0.4" },
+ { name = "products-cmfdynamicviewfti", specifier = "==7.0.2" },
+ { name = "products-cmfeditions", specifier = "==4.0.5" },
+ { name = "products-cmfplacefulworkflow", specifier = "==3.0.5" },
+ { name = "products-cmfplone", specifier = "==6.1.1" },
+ { name = "products-cmfuid", specifier = "==4.2" },
+ { name = "products-daterecurringindex", specifier = "==3.0.1" },
+ { name = "products-dcworkflow", specifier = "==3.0" },
+ { name = "products-extendedpathindex", specifier = "==4.0.1" },
+ { name = "products-externalmethod", specifier = "==6.0" },
+ { name = "products-genericsetup", specifier = "==5.0.0" },
+ { name = "products-isurlinportal", specifier = "==3.0.0" },
+ { name = "products-mailhost", specifier = "==6.0" },
+ { name = "products-mimetypesregistry", specifier = "==3.0.1" },
+ { name = "products-pdbdebugmode", specifier = "==2.0" },
+ { name = "products-plonepas", specifier = "==8.0.5" },
+ { name = "products-pluggableauthservice", specifier = "==3.0" },
+ { name = "products-pluginregistry", specifier = "==2.0" },
+ { name = "products-portaltransforms", specifier = "==4.1.1" },
+ { name = "products-printingmailhost", specifier = "==1.1.7" },
+ { name = "products-pythonscripts", specifier = "==5.1" },
+ { name = "products-sessions", specifier = "==5.0" },
+ { name = "products-siteerrorlog", specifier = "==6.0" },
+ { name = "products-standardcachemanagers", specifier = "==5.0" },
+ { name = "products-statusmessages", specifier = "==5.0.6" },
+ { name = "products-validation", specifier = "==3.0.0" },
+ { name = "products-zcatalog", specifier = "==7.1" },
+ { name = "products-zopeversioncontrol", specifier = "==4.1" },
+ { name = "progress", specifier = "==1.6" },
+ { name = "prompt-toolkit", specifier = "==3.0.48" },
+ { name = "psycopg2", specifier = "==2.9.10" },
+ { name = "py", specifier = "==1.11.0" },
+ { name = "pycparser", specifier = "==2.22" },
+ { name = "pygithub", specifier = "==2.5.0" },
+ { name = "pygments", specifier = "==2.19.1" },
+ { name = "pyjwt", specifier = "==2.10.1" },
+ { name = "pynacl", specifier = "==1.5.0" },
+ { name = "pyopenssl", specifier = "==24.3.0" },
+ { name = "pyparsing", specifier = "==3.2.0" },
+ { name = "pyproject-hooks", specifier = "==1.2.0" },
+ { name = "pyrepl", specifier = "==0.9.0" },
+ { name = "pyroma", specifier = "==4.2" },
+ { name = "pyrsistent", specifier = "==0.20.0" },
+ { name = "pysocks", specifier = "==1.7.1" },
+ { name = "pytest", specifier = "==7.4.4" },
+ { name = "pytest-cov", specifier = "==6.1.1" },
+ { name = "pytest-plone", specifier = ">=1.0.0a1" },
+ { name = "python-dateutil", specifier = "==2.9.0.post0" },
+ { name = "python-dotenv", specifier = "==1.0.1" },
+ { name = "python-gettext", specifier = "==5.0" },
+ { name = "pytz", specifier = "==2024.2" },
+ { name = "pywin32-ctypes", marker = "sys_platform == 'win32'", specifier = "==0.2.3" },
+ { name = "pyyaml", specifier = "==6.0.2" },
+ { name = "readme-renderer", specifier = "==44.0" },
+ { name = "record", specifier = "==4.1" },
+ { name = "referencing", specifier = "==0.35.1" },
+ { name = "relstorage", specifier = "==4.1.1" },
+ { name = "repoze-xmliter", specifier = "==1.0b1" },
+ { name = "requests", specifier = "==2.32.3" },
+ { name = "requests-toolbelt", specifier = "==1.0.0" },
+ { name = "responses", specifier = "==0.25.3" },
+ { name = "restrictedpython", specifier = "==8.0" },
+ { name = "rfc3986", specifier = "==2.0.0" },
+ { name = "rich", specifier = "==13.9.4" },
+ { name = "robotframework", specifier = "==6.0.2" },
+ { name = "robotframework-assertion-engine", specifier = "==3.0.3" },
+ { name = "robotframework-browser", specifier = "==19.3.1" },
+ { name = "robotframework-debuglibrary", specifier = "==2.5.0" },
+ { name = "robotframework-lsp", specifier = "==1.10.1" },
+ { name = "robotframework-pythonlibcore", specifier = "==4.4.1" },
+ { name = "robotframework-selenium2library", specifier = "==3.0.0" },
+ { name = "robotframework-selenium2screenshots", specifier = "==0.8.1" },
+ { name = "robotframework-seleniumlibrary", specifier = "==6.1.3" },
+ { name = "robotframework-seleniumtestability", specifier = "==2.1.0" },
+ { name = "robotsuite", specifier = "==2.3.2" },
+ { name = "roman", specifier = "==5.0" },
+ { name = "rpds-py", specifier = "==0.22.3" },
+ { name = "secretstorage", specifier = "==3.3.3" },
+ { name = "seedir", specifier = "==0.5.0" },
+ { name = "selenium", specifier = "==4.9.1" },
+ { name = "setuptools", specifier = "==75.8.2" },
+ { name = "sgmllib3k", specifier = "==1.0.0" },
+ { name = "simplejson", specifier = "==3.19.3" },
+ { name = "six", specifier = "==1.17.0" },
+ { name = "smmap", specifier = "==5.0.1" },
+ { name = "sniffio", specifier = "==1.3.1" },
+ { name = "snowballstemmer", specifier = "==2.2.0" },
+ { name = "sortedcontainers", specifier = "==2.4.0" },
+ { name = "soupsieve", specifier = "==2.6" },
+ { name = "sphinx", marker = "python_full_version == '3.9.*'", specifier = "==7.4.7" },
+ { name = "sphinx", marker = "python_full_version >= '3.10'", specifier = "==8.1.3" },
+ { name = "sphinx-basic-ng", specifier = "==1.0.0b2" },
+ { name = "sphinxcontrib-applehelp", specifier = "==2.0.0" },
+ { name = "sphinxcontrib-devhelp", specifier = "==2.0.0" },
+ { name = "sphinxcontrib-htmlhelp", specifier = "==2.1.0" },
+ { name = "sphinxcontrib-jsmath", specifier = "==1.0.1" },
+ { name = "sphinxcontrib-qthelp", specifier = "==2.0.0" },
+ { name = "sphinxcontrib-serializinghtml", specifier = "==2.0.0" },
+ { name = "stdlib-list", specifier = "==0.11.0" },
+ { name = "tempstorage", specifier = "==6.0" },
+ { name = "toml", specifier = "==0.10.2" },
+ { name = "tomli", specifier = "==2.2.1" },
+ { name = "towncrier", specifier = "==24.8.0" },
+ { name = "transaction", specifier = "==5.0" },
+ { name = "trio", specifier = "==0.27.0" },
+ { name = "trio-websocket", specifier = "==0.11.1" },
+ { name = "trove-classifiers", specifier = "==2025.2.18.16" },
+ { name = "twine", specifier = "==5.1.1" },
+ { name = "types-pyyaml", specifier = "==6.0.12.10" },
+ { name = "types-toml", specifier = "==0.10.8.5" },
+ { name = "typing-extensions", specifier = "==4.12.2" },
+ { name = "tzdata", specifier = "==2025.1" },
+ { name = "unidecode", specifier = "==1.3.8" },
+ { name = "urllib3", specifier = "==2.3.0" },
+ { name = "urllib3-secure-extra", specifier = "==0.1.0" },
+ { name = "wadllib", specifier = "==2.0.0" },
+ { name = "waitress", specifier = "==3.0.2" },
+ { name = "watchdog", specifier = "==6.0.0" },
+ { name = "wcwidth", specifier = "==0.2.13" },
+ { name = "webencodings", specifier = "==0.5.1" },
+ { name = "webob", specifier = "==1.8.9" },
+ { name = "webresource", specifier = "==1.2" },
+ { name = "webtest", specifier = "==3.0.3" },
+ { name = "wheel", specifier = "==0.45.1" },
+ { name = "wmctrl", specifier = "==0.5" },
+ { name = "wrapt", specifier = "==1.17.0" },
+ { name = "wsgiproxy2", specifier = "==0.5.1" },
+ { name = "wsproto", specifier = "==1.2.0" },
+ { name = "z3c-caching", specifier = "==3.0" },
+ { name = "z3c-checkversions", specifier = "==2.1" },
+ { name = "z3c-dependencychecker", specifier = "==2.15" },
+ { name = "z3c-form", specifier = "==5.1" },
+ { name = "z3c-formwidget-query", specifier = "==2.0.0" },
+ { name = "z3c-jbot", specifier = "==2.0" },
+ { name = "z3c-objpath", specifier = "==2.0" },
+ { name = "z3c-pt", specifier = "==4.4" },
+ { name = "z3c-relationfield", specifier = "==2.0.0" },
+ { name = "z3c-unconfigure", specifier = "==2.1" },
+ { name = "z3c-zcmlhook", specifier = "==2.0" },
+ { name = "zc-buildout", specifier = "==4.1.4" },
+ { name = "zc-lockfile", specifier = "==3.0.post1" },
+ { name = "zc-recipe-egg", specifier = "==2.0.7" },
+ { name = "zc-recipe-testrunner", specifier = "==3.1" },
+ { name = "zc-relation", specifier = "==2.0" },
+ { name = "zconfig", specifier = "==4.2" },
+ { name = "zdaemon", specifier = "==5.1" },
+ { name = "zeo", specifier = "==6.0.0" },
+ { name = "zest-pocompile", specifier = "==2.0.0" },
+ { name = "zest-releaser", specifier = "==9.5.0" },
+ { name = "zestreleaser-towncrier", specifier = "==1.3.0" },
+ { name = "zexceptions", specifier = "==5.0" },
+ { name = "zipp", specifier = "==3.21.0" },
+ { name = "zodb", specifier = "==6.0" },
+ { name = "zodb3", specifier = "==3.11.0" },
+ { name = "zodbpickle", specifier = "==4.1.1" },
+ { name = "zodbupdate", specifier = "==2.0" },
+ { name = "zodbverify", specifier = "==1.2.0" },
+ { name = "zope", specifier = "==5.13" },
+ { name = "zope-annotation", specifier = "==5.0" },
+ { name = "zope-app-locales", specifier = "==5.0" },
+ { name = "zope-browser", specifier = "==3.0" },
+ { name = "zope-browsermenu", specifier = "==5.0" },
+ { name = "zope-browserpage", specifier = "==5.0" },
+ { name = "zope-browserresource", specifier = "==5.1" },
+ { name = "zope-cachedescriptors", specifier = "==5.0" },
+ { name = "zope-component", specifier = "==6.0" },
+ { name = "zope-componentvocabulary", specifier = "==2.3.0" },
+ { name = "zope-configuration", specifier = "==6.0" },
+ { name = "zope-container", specifier = "==6.1" },
+ { name = "zope-contentprovider", specifier = "==6.0" },
+ { name = "zope-contenttype", specifier = "==5.1" },
+ { name = "zope-copy", specifier = "==5.0" },
+ { name = "zope-datetime", specifier = "==5.0.0" },
+ { name = "zope-deferredimport", specifier = "==5.0" },
+ { name = "zope-deprecation", specifier = "==5.1" },
+ { name = "zope-dottedname", specifier = "==6.0" },
+ { name = "zope-event", specifier = "==5.0" },
+ { name = "zope-exceptions", specifier = "==5.2" },
+ { name = "zope-filerepresentation", specifier = "==6.0" },
+ { name = "zope-globalrequest", specifier = "==2.0" },
+ { name = "zope-hookable", specifier = "==7.0" },
+ { name = "zope-i18n", specifier = "==5.2" },
+ { name = "zope-i18nmessageid", specifier = "==7.0" },
+ { name = "zope-interface", specifier = "==7.2" },
+ { name = "zope-intid", specifier = "==5.0" },
+ { name = "zope-keyreference", specifier = "==6.0" },
+ { name = "zope-lifecycleevent", specifier = "==5.0" },
+ { name = "zope-location", specifier = "==5.0" },
+ { name = "zope-mkzeoinstance", specifier = "==6.0" },
+ { name = "zope-pagetemplate", specifier = "==5.1" },
+ { name = "zope-processlifetime", specifier = "==3.0" },
+ { name = "zope-proxy", specifier = "==6.1" },
+ { name = "zope-ptresource", specifier = "==5.0" },
+ { name = "zope-publisher", specifier = "==7.3" },
+ { name = "zope-pytestlayer", specifier = "==8.2" },
+ { name = "zope-ramcache", specifier = "==3.0" },
+ { name = "zope-schema", specifier = "==7.0.1" },
+ { name = "zope-security", specifier = "==7.3" },
+ { name = "zope-sendmail", specifier = "==6.2" },
+ { name = "zope-sequencesort", specifier = "==5.0" },
+ { name = "zope-site", specifier = "==5.0" },
+ { name = "zope-size", specifier = "==5.0" },
+ { name = "zope-structuredtext", specifier = "==5.0" },
+ { name = "zope-tal", specifier = "==5.0.1" },
+ { name = "zope-tales", specifier = "==6.0" },
+ { name = "zope-testbrowser", specifier = "==7.0" },
+ { name = "zope-testing", specifier = "==5.0.1" },
+ { name = "zope-testrunner", specifier = "==7.2" },
+ { name = "zope-traversing", specifier = "==5.0" },
+ { name = "zope-viewlet", specifier = "==5.0" },
+ { name = "zope2", specifier = "==4.0" },
+ { name = "zopeundo", specifier = "==6.0" },
+]
+
+[[package]]
+name = "accesscontrol"
+version = "7.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "authencoding" },
+ { name = "btrees" },
+ { name = "datetime" },
+ { name = "extensionclass" },
+ { name = "persistence" },
+ { name = "restrictedpython" },
+ { name = "transaction" },
+ { name = "zexceptions" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-deferredimport" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/63/12/cfaae50dbd4e570847e19d2834235bcf449ab174f2ea5616cab0c7f009bd/accesscontrol-7.2.tar.gz", hash = "sha256:5a0e84b8b775a63826082a8697e75aad8131077d821d35ee7ce63f704a06ff43", size = 114439 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8d/dd/78238bd23020cf99e03b850813f6c486486f3abd8345257dcbd3eff54726/AccessControl-7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54e74c681754457c5471a77cad32d539432b8b333f3c058271858737f1d39378", size = 141830 },
+ { url = "https://files.pythonhosted.org/packages/1b/d2/3f98cf0ae4faf458afac3f18aa683b7b83e84d4de25fee972b473fd3bd7b/AccessControl-7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e19f58685e63aed611448344651a8aa7f61e50674b88a1119ee31c40c205fd3a", size = 141976 },
+ { url = "https://files.pythonhosted.org/packages/94/ae/db4344a41c02522df5854d0edce3b638a92c1b037bd4d6b36f65d677b193/AccessControl-7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f587a269a99ff4d7335008dc1bdfe219696b746859c306c7cabecd3afd775a3", size = 201018 },
+ { url = "https://files.pythonhosted.org/packages/55/ef/ef880c9f10dbfa20d7cc4ba17fd8e6cfe49afbae8ea731d687c524438d98/AccessControl-7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13b68217275fb038b69234e0b9cb3ec1b4ab3dcdc752eb65a06df95ac4586623", size = 196783 },
+ { url = "https://files.pythonhosted.org/packages/75/5e/f769db2e8389f36fcc50ab60083719e06ce6e122d2028993d17f1d74e2fb/AccessControl-7.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a92cbe0ab08f3c8680079f5c2ee0e10de68bc60fb92454f71d269e6aeaf7ca09", size = 202092 },
+ { url = "https://files.pythonhosted.org/packages/4c/52/4520b35508b486adcc9c0724ad4b61a818ab6f26148f5009e284af66c9e8/AccessControl-7.2-cp312-cp312-win_amd64.whl", hash = "sha256:32ae5837702356ca302fde16bb796961d27715e958ca8bde27c8eeb08b708e5d", size = 144254 },
+ { url = "https://files.pythonhosted.org/packages/69/0a/0109170d5a7fd962dcd06a1afea50791858907f0e196993ee6188a1470e3/AccessControl-7.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:3155f57b00c680d5efbd76e51c42ab2a930cb257675f5a4b725cd8928c2be6dc", size = 141801 },
+ { url = "https://files.pythonhosted.org/packages/d8/56/95badf5e50370abc020b16246f7b84d72c114b6e16602ae47c7d7b4720aa/AccessControl-7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:844242ff91cf20908863eb78c682276e37abfd4dc5491f19a7947f7703cdfea1", size = 141944 },
+ { url = "https://files.pythonhosted.org/packages/8e/85/207f9cfed81eddbc4637d6f549d9dbcfe3e9a21178ddce673f76a67377b8/AccessControl-7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8aaae5928084f1918814e5c3134857dad9961598c890f80d86e47d5a13c86d1f", size = 200973 },
+ { url = "https://files.pythonhosted.org/packages/fc/30/2be52a2f8f14ef4acca7e6c8df18869391eaa88cf3be4619664028a3e16b/AccessControl-7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a9b2bf2b5858a63cb3947b235017991bf526d61ffe29575a0eba0be147194f", size = 196700 },
+ { url = "https://files.pythonhosted.org/packages/bb/f2/26add981f1bacaa206c745019ad120bd90d8ccddad316b06014e3105b21d/AccessControl-7.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb36ff878a070edb7f25356c64327b2d11e4d52fa348391eb244a0c3bf1a7be", size = 202074 },
+ { url = "https://files.pythonhosted.org/packages/81/26/0a2b17864e034b207016d3067afae30ffa30ac3b545dfc96478ae4108c1c/AccessControl-7.2-cp313-cp313-win_amd64.whl", hash = "sha256:6b79330739939c7979c972e3c8b3b997650048d87655cc213a310d5b5eb30742", size = 144257 },
+]
+
+[[package]]
+name = "acquisition"
+version = "6.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "extensionclass" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/67/9a/3df1e83e6655ca6eee9920f746455b9865c7dff9ef5ca9dadb683fb38c02/acquisition-6.1.tar.gz", hash = "sha256:e88b296d6ec5fcb63194deb91d8c4df37150dcae149ede4e1aeb115d042e9378", size = 65561 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7f/0e/054da462818895a0112b8c45164e123b2fd940459c4106f93afee2478e6e/Acquisition-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0c82221d6563b1d4da15ee2d04d2e1e414beca07e419ca11d678fe2296445d22", size = 64715 },
+ { url = "https://files.pythonhosted.org/packages/01/ef/491b2f66eefa8428562aa7a8065a0f809276f083ba6944c372a2bc737e59/Acquisition-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:16e6ef44d626dfcfa69fa8481212db536be26fbd831f3810ad305d1514ee5f50", size = 64334 },
+ { url = "https://files.pythonhosted.org/packages/20/59/2683ef5c750dfb1015857428bcb682f4334a045c5059f6c19c6c8a61adb6/Acquisition-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57efad980a9055485b6bddc785f1a13cae16606bf88e20e00b461d0cbdc4f7f9", size = 121907 },
+ { url = "https://files.pythonhosted.org/packages/d1/d2/5d7fdad1e93e1773f9ef94c1ee8eb37f66d50770ff0a8397d844f3677b21/Acquisition-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1bce20e2b285a675ffdc0c7587b530366dbec120c960da75db29dc9685431a2", size = 114213 },
+ { url = "https://files.pythonhosted.org/packages/38/a5/65c2841fd68caf8e62e554fb7fdb24b8706b396f0ae885507dd819bf98cb/Acquisition-6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8b05bd67cf835f756a73cfb6f02eaf28bb0cad6f96097f479fdd7a17d5c444", size = 122089 },
+ { url = "https://files.pythonhosted.org/packages/9f/2b/0f3a80bae17d9fcac17d1dbc0ab06f14a7751b9bf6b24b9b3114bee27de2/Acquisition-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:571c3ef9f5e90e3f5b70709bba4df2d4a66889334c9bc00be88fec4123279418", size = 65739 },
+ { url = "https://files.pythonhosted.org/packages/98/2d/85fb469da1cfd704a50b3d0ae367aba16013cb22ee526adec56c4415cef1/Acquisition-6.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:3e2115def6d944b054c57215b5acb8f1dec8ee3c2e80d4577dd5666dd3281217", size = 64754 },
+ { url = "https://files.pythonhosted.org/packages/f3/83/761e8f0e01a36d848cc1c22d8dd2b59fda0fad3466df369fbfed40dafb28/Acquisition-6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:314cee791a819f5145dada1336682c6ba93ec33ccd6ee478fea69ce41c67cdbe", size = 64364 },
+ { url = "https://files.pythonhosted.org/packages/5c/11/a857a37ee1f84bcff8c61de300b72fdfab3d7af739f36d9e0b9d99445005/Acquisition-6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da428b419eacd79930e8f27c0a2efbb32dc113402211696dfa6dc1627500148e", size = 121938 },
+ { url = "https://files.pythonhosted.org/packages/77/50/ef82fd6bd6f9e3bd6f0e37361d61ef9f693e6490becac109b46461b45950/Acquisition-6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05b93dbf29cbdb292557a6777aa0aab07acfa622764bc760facd1eab4b5415f9", size = 114207 },
+ { url = "https://files.pythonhosted.org/packages/9e/99/ce406017db5f4698fce40b631682ffaf71ca878d1e8c9f715f0029b35163/Acquisition-6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:127ee652eae6a0196443f69ccbd2362d9f5e28fd6eb6a178d3daa21276179355", size = 122061 },
+ { url = "https://files.pythonhosted.org/packages/b0/9c/2ed62813b108f090f9e8939aba4b281ebedb4fbf213b32e014eb81546358/Acquisition-6.1-cp313-cp313-win_amd64.whl", hash = "sha256:35da0b71db5b02376a40d6f342776619979767f30d8dcd06cea45e0a8fb92e5d", size = 65758 },
+]
+
+[[package]]
+name = "attrs"
+version = "24.2.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 },
+]
+
+[[package]]
+name = "authencoding"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/41/0c/853715b6b26a90683cd060186b877d8431eb4b38507030de20a696eec13a/authencoding-6.0.tar.gz", hash = "sha256:9b7ed85772cd28f35aa035276b566c038a44cce0cffeb6cb90df06a6caa0b0bb", size = 10668 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/65/15/716495cf0759c1dd8e449afb26cda840e3378b7b5afd47f63c8045434d1e/AuthEncoding-6.0-py3-none-any.whl", hash = "sha256:4c1a8c3db8222a9892a947d77fde7db3b4be224bbcf0765762e44abdb4da3a0c", size = 9092 },
+]
+
+[[package]]
+name = "babel"
+version = "2.16.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 },
+]
+
+[[package]]
+name = "beautifulsoup4"
+version = "4.12.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "soupsieve" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 },
+]
+
+[[package]]
+name = "borg-localrole"
+version = "3.1.11"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "plone-memoize" },
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "products-plonepas" },
+ { name = "products-pluggableauthservice" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-annotation" },
+ { name = "zope-component" },
+ { name = "zope-deferredimport" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/40/cc/3c2e37418aa3c1ebba0412041ab813d51a97bea4c845eec7b8c78c2e010a/borg.localrole-3.1.11.tar.gz", hash = "sha256:bf1e59a1246501244a3680d6596a90ab1726708f97e8deedd1a2229adfc3aa65", size = 18373 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c8/a5/7f9925e98f806e5a06362b8ce7be8da77892d2fc586377aab6a14b4ea82a/borg.localrole-3.1.11-py3-none-any.whl", hash = "sha256:ff55447091aadb0d6bff9b3ea7628b11e08d9c57e52b0587b929424926b5f2f8", size = 19157 },
+]
+
+[[package]]
+name = "btrees"
+version = "6.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/4b/bd/5dd0c5bd5ac2d518c18bc3f4746028f931d77b4d4b83cbcb8c4271ab465b/btrees-6.1.tar.gz", hash = "sha256:e18746f8641869a20f45328c9b5f97dc6c71a1195960356aef63b75f5c8d445f", size = 244735 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/40/ee/e14c946da5ed8eb7c017739de4403a55d45083780bcc18e2576d761e7274/BTrees-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:913890a8f5cce402fda7a06d9eaaf4ddda64a042e5c764c38fe5fb2004099072", size = 990596 },
+ { url = "https://files.pythonhosted.org/packages/be/88/0891d74c3167b207aa26d3cb115307c11901549ae820ae2d1494bbccf734/BTrees-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:407648d72812b19bea2a3f98a2188a17121e9b5add0c12416f8bcecd724cec0b", size = 973285 },
+ { url = "https://files.pythonhosted.org/packages/85/63/0e73cb647ed166cc356188b602af53f03df2767b6c7ed9ea5524533bab95/BTrees-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:860b3b6f0d5d4b34e6168e6490d0b26586e8b6c33cad7d5893f97fa3f4b3ff16", size = 3092986 },
+ { url = "https://files.pythonhosted.org/packages/06/4d/ab182d08fec99f11bc3e8488987b7a8b715c73ba8d75e9d2cd466d09a52a/BTrees-6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:789a5b858cbee0a4750e7e3b4c13a1e47e6b9c7be50329087e621bff6d81154e", size = 4155280 },
+ { url = "https://files.pythonhosted.org/packages/3b/56/c909afd214bf76cce8e2d81f683872db7ddf180923bd77153e3bad31a783/BTrees-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a76dbeed484720cf7aa231f3552665df91bda0dbb357aab5fefefde133eef89e", size = 3848016 },
+ { url = "https://files.pythonhosted.org/packages/3c/d5/46f0690def7d134519cbed723e4b5b8e12e7975533238594a75a69ea8cad/BTrees-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b4e2a878acdb9e1087c71e8914909a3d582617c496adea8a02bc839285666b0f", size = 1039797 },
+ { url = "https://files.pythonhosted.org/packages/80/50/19f41c9e1b5022d8ce02fe98be25749b781d005c9562f1b8f9fc14f737b9/BTrees-6.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:6a7acd17e2934536012445ba33e2805f71e65b9bc9a8683013626fb3fc6824a9", size = 990651 },
+ { url = "https://files.pythonhosted.org/packages/97/cf/6efb2586732c4026d32fafe5128fc4322c2428979b6521fad59d9e683ecb/BTrees-6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:58383635a06532ab6ee66bd1ba20e56af627e7a91665f1d98a8d550890e608d7", size = 973360 },
+ { url = "https://files.pythonhosted.org/packages/67/b7/cbc0ee83cb1f7874f5e4e0d05d1a779b2d8ab7589aa2d377cc7f34dca812/BTrees-6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:398b9bc27d563197fc2966e237742019f7abc3d622a98c710155ca2bac421e3e", size = 3093041 },
+ { url = "https://files.pythonhosted.org/packages/81/c0/22f15c1cda65a2422e11127a4d9db346bb9f5b456fae78c7504ca38a1159/BTrees-6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8f2936e75321e7ce652b0092aaf41f88cc98bf3b70d2dcca2ef8e38bf5b2e44", size = 4156271 },
+ { url = "https://files.pythonhosted.org/packages/5c/28/afb6fc23928a0ddfc6388c7d82b3287c3be9eb6b48e519d4bf6453cc8a22/BTrees-6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13ae3f198ad09f62b8fe575d7e63de19c8eabe11568f73f033a48f095debfe6c", size = 3848507 },
+ { url = "https://files.pythonhosted.org/packages/df/66/a238cc0b3811c28da4cf515f1928de2e51dce178d5260d467f4827b57c49/BTrees-6.1-cp313-cp313-win_amd64.whl", hash = "sha256:71448fa70a6e1cdb21a653043fb23df96e8b24c2c1ff93cc1dac818412f1aecc", size = 1039990 },
+]
+
+[[package]]
+name = "certifi"
+version = "2024.12.14"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 },
+]
+
+[[package]]
+name = "cffi"
+version = "1.17.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pycparser" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 },
+ { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 },
+ { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 },
+ { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 },
+ { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 },
+ { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 },
+ { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 },
+ { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 },
+ { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 },
+ { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 },
+ { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 },
+ { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 },
+ { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 },
+ { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 },
+ { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 },
+ { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 },
+ { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 },
+ { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 },
+ { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 },
+ { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 },
+ { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 },
+ { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 },
+]
+
+[[package]]
+name = "chameleon"
+version = "4.4.4"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/72/89/77794f86c7c7ad8fc6b5502e579e917344ce803b6519a03809f1117a0a97/Chameleon-4.4.4.tar.gz", hash = "sha256:a0e8109a9215dc673a1130148c826ff4df9cf7140f384a7801b18923345a97eb", size = 178432 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e9/fc/0c41a908393ed74c1d2025836f5cf16213bf2dd6a278d0a7c94589fde337/Chameleon-4.4.4-py3-none-any.whl", hash = "sha256:5b84e4e3d1c0f4d96ec75cafbfe113b31956fbcd8f1bc008eb9da7b85b329061", size = 87061 },
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.4.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 },
+ { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 },
+ { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 },
+ { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 },
+ { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 },
+ { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 },
+ { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 },
+ { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 },
+ { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 },
+ { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 },
+ { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 },
+ { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 },
+ { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 },
+ { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 },
+ { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 },
+ { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 },
+ { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 },
+ { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 },
+ { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 },
+ { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 },
+ { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 },
+ { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 },
+ { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 },
+ { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 },
+ { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 },
+ { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 },
+ { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
+]
+
+[[package]]
+name = "click"
+version = "8.1.7"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 },
+]
+
+[[package]]
+name = "collective-honeypot"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "z3c-jbot" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/aa/83/0190a04d5900a8695b7abaef3173d2c3ebf15628c3b01e430327dc70b4f6/collective.honeypot-3.0.0.tar.gz", hash = "sha256:d72bf6bc54bfc082bf9cba8c5db3e81c579a5c9cdda724af4f5f81c529bf60a5", size = 39000 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fb/de/bf0f94ea0ffe5aedcf22a18ce7a89ea67bfaf04c3b433cc318a7d192724d/collective.honeypot-3.0.0-py3-none-any.whl", hash = "sha256:e6eb9ebf8be11bafa374751f8d0d944d782bfdfc992e111fa2d471a7b5e5af03", size = 38968 },
+]
+
+[[package]]
+name = "collective-mockmailhost"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "products-mailhost" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/19/48/18aa36e82d58f97ee04a216cd9a90d76f56ef8d6482d6c3d007fab5d77a3/collective.MockMailHost-3.0.0.tar.gz", hash = "sha256:392071e1037d19851c7e209efd681e9830c11356226fc17c23f3e671b8ca9f06", size = 19556 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2b/99/51cdac9f189de8f9c7882dd845fa6e8aece928419ebb90ba5005a0f67ccb/collective.MockMailHost-3.0.0-py2.py3-none-any.whl", hash = "sha256:a008be95e6e85afff75310156cde30462b20435a1223d0ca791bc6962a61118d", size = 12530 },
+]
+
+[[package]]
+name = "collective-monkeypatcher"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-configuration" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fa/cc/bbf464658c49853931c1a0923e522a8bcdf7ef1ec44b8ec5a82015e5136f/collective_monkeypatcher-2.0.0.tar.gz", hash = "sha256:8792dade3eec1590a8b235bacf41e062bc3cf8ad2093e181c730ec6bd6497ab2", size = 17016 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/84/89/02f5a44aeae4a415c2c93ae4174941fa1b99669d91705e58161afa8613f4/collective_monkeypatcher-2.0.0-py3-none-any.whl", hash = "sha256:8cde16accc65770ddc7a151540267c711d44afb1e7ce3815711b39c6497ad628", size = 12930 },
+]
+
+[[package]]
+name = "collective-volto-formsupport"
+version = "3.2.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "beautifulsoup4" },
+ { name = "click" },
+ { name = "collective-volto-otp" },
+ { name = "plone-api" },
+ { name = "plone-dexterity" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-restapi" },
+ { name = "plone-schema" },
+ { name = "products-genericsetup" },
+ { name = "products-portaltransforms" },
+ { name = "setuptools" },
+ { name = "souper-plone" },
+ { name = "z3c-jbot" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/7c/dc/b7801afe05fe16c00ff27c3ef507cfcb45801553be36e71ce6ae95adbf66/collective.volto.formsupport-3.2.3.tar.gz", hash = "sha256:6dc7f937ff8eb8c0bf7f7e223b663b3333b23220d5378547130b2f5c71ab73f2", size = 136291 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/39/b0/37ba599e95054fdb5b43f200cbcb8ed56dd0301d2c4208bca5d1604efb21/collective.volto.formsupport-3.2.3-py3-none-any.whl", hash = "sha256:af9145c619738050150f865d31263ed3812fd99522700cd51e7225f17fc05d72", size = 157346 },
+]
+
+[[package]]
+name = "collective-volto-otp"
+version = "1.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-api" },
+ { name = "plone-app-dexterity" },
+ { name = "pyotp" },
+ { name = "setuptools" },
+ { name = "z3c-jbot" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/40/b2/943899f15dd832e1f004318fa77fa5fe825eebccd237e750efa64c1abd43/collective.volto.otp-1.0.1.tar.gz", hash = "sha256:8b54dd62995a61a0318bed48e4f8f2d4da5984a73d333d6359d425f71a0c58d1", size = 28687 }
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
+]
+
+[[package]]
+name = "coverage"
+version = "7.6.9"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/5b/d2/c25011f4d036cf7e8acbbee07a8e09e9018390aee25ba085596c4b83d510/coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d", size = 801710 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/60/52/b16af8989a2daf0f80a88522bd8e8eed90b5fcbdecf02a6888f3e80f6ba7/coverage-7.6.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:99e266ae0b5d15f1ca8d278a668df6f51cc4b854513daab5cae695ed7b721cf8", size = 207325 },
+ { url = "https://files.pythonhosted.org/packages/0f/79/6b7826fca8846c1216a113227b9f114ac3e6eacf168b4adcad0cb974aaca/coverage-7.6.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9901d36492009a0a9b94b20e52ebfc8453bf49bb2b27bca2c9706f8b4f5a554a", size = 207563 },
+ { url = "https://files.pythonhosted.org/packages/a7/07/0bc73da0ccaf45d0d64ef86d33b7d7fdeef84b4c44bf6b85fb12c215c5a6/coverage-7.6.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd3e72dd5b97e3af4246cdada7738ef0e608168de952b837b8dd7e90341f015", size = 240580 },
+ { url = "https://files.pythonhosted.org/packages/71/8a/9761f409910961647d892454687cedbaccb99aae828f49486734a82ede6e/coverage-7.6.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff74026a461eb0660366fb01c650c1d00f833a086b336bdad7ab00cc952072b3", size = 237613 },
+ { url = "https://files.pythonhosted.org/packages/8b/10/ee7d696a17ac94f32f2dbda1e17e730bf798ae9931aec1fc01c1944cd4de/coverage-7.6.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dad5a248823a4996724a88eb51d4b31587aa7aa428562dbe459c684e5787ae", size = 239684 },
+ { url = "https://files.pythonhosted.org/packages/16/60/aa1066040d3c52fff051243c2d6ccda264da72dc6d199d047624d395b2b2/coverage-7.6.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22be16571504c9ccea919fcedb459d5ab20d41172056206eb2994e2ff06118a4", size = 239112 },
+ { url = "https://files.pythonhosted.org/packages/4e/e5/69f35344c6f932ba9028bf168d14a79fedb0dd4849b796d43c81ce75a3c9/coverage-7.6.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f957943bc718b87144ecaee70762bc2bc3f1a7a53c7b861103546d3a403f0a6", size = 237428 },
+ { url = "https://files.pythonhosted.org/packages/32/20/adc895523c4a28f63441b8ac645abd74f9bdd499d2d175bef5b41fc7f92d/coverage-7.6.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ae1387db4aecb1f485fb70a6c0148c6cdaebb6038f1d40089b1fc84a5db556f", size = 239098 },
+ { url = "https://files.pythonhosted.org/packages/a9/a6/e0e74230c9bb3549ec8ffc137cfd16ea5d56e993d6bffed2218bff6187e3/coverage-7.6.9-cp312-cp312-win32.whl", hash = "sha256:1a330812d9cc7ac2182586f6d41b4d0fadf9be9049f350e0efb275c8ee8eb692", size = 209940 },
+ { url = "https://files.pythonhosted.org/packages/3e/18/cb5b88349d4aa2f41ec78d65f92ea32572b30b3f55bc2b70e87578b8f434/coverage-7.6.9-cp312-cp312-win_amd64.whl", hash = "sha256:b12c6b18269ca471eedd41c1b6a1065b2f7827508edb9a7ed5555e9a56dcfc97", size = 210726 },
+ { url = "https://files.pythonhosted.org/packages/35/26/9abab6539d2191dbda2ce8c97b67d74cbfc966cc5b25abb880ffc7c459bc/coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664", size = 207356 },
+ { url = "https://files.pythonhosted.org/packages/44/da/d49f19402240c93453f606e660a6676a2a1fbbaa6870cc23207790aa9697/coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c", size = 207614 },
+ { url = "https://files.pythonhosted.org/packages/da/e6/93bb9bf85497816082ec8da6124c25efa2052bd4c887dd3b317b91990c9e/coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014", size = 240129 },
+ { url = "https://files.pythonhosted.org/packages/df/65/6a824b9406fe066835c1274a9949e06f084d3e605eb1a602727a27ec2fe3/coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00", size = 237276 },
+ { url = "https://files.pythonhosted.org/packages/9f/79/6c7a800913a9dd23ac8c8da133ebb556771a5a3d4df36b46767b1baffd35/coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d", size = 239267 },
+ { url = "https://files.pythonhosted.org/packages/57/e7/834d530293fdc8a63ba8ff70033d5182022e569eceb9aec7fc716b678a39/coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a", size = 238887 },
+ { url = "https://files.pythonhosted.org/packages/15/05/ec9d6080852984f7163c96984444e7cd98b338fd045b191064f943ee1c08/coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077", size = 236970 },
+ { url = "https://files.pythonhosted.org/packages/0a/d8/775937670b93156aec29f694ce37f56214ed7597e1a75b4083ee4c32121c/coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb", size = 238831 },
+ { url = "https://files.pythonhosted.org/packages/f4/58/88551cb7fdd5ec98cb6044e8814e38583436b14040a5ece15349c44c8f7c/coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba", size = 210000 },
+ { url = "https://files.pythonhosted.org/packages/b7/12/cfbf49b95120872785ff8d56ab1c7fe3970a65e35010c311d7dd35c5fd00/coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1", size = 210753 },
+ { url = "https://files.pythonhosted.org/packages/7c/68/c1cb31445599b04bde21cbbaa6d21b47c5823cdfef99eae470dfce49c35a/coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419", size = 208091 },
+ { url = "https://files.pythonhosted.org/packages/11/73/84b02c6b19c4a11eb2d5b5eabe926fb26c21c080e0852f5e5a4f01165f9e/coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a", size = 208369 },
+ { url = "https://files.pythonhosted.org/packages/de/e0/ae5d878b72ff26df2e994a5c5b1c1f6a7507d976b23beecb1ed4c85411ef/coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4", size = 251089 },
+ { url = "https://files.pythonhosted.org/packages/ab/9c/0aaac011aef95a93ef3cb2fba3fde30bc7e68a6635199ed469b1f5ea355a/coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae", size = 246806 },
+ { url = "https://files.pythonhosted.org/packages/f8/19/4d5d3ae66938a7dcb2f58cef3fa5386f838f469575b0bb568c8cc9e3a33d/coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030", size = 249164 },
+ { url = "https://files.pythonhosted.org/packages/b3/0b/4ee8a7821f682af9ad440ae3c1e379da89a998883271f088102d7ca2473d/coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be", size = 248642 },
+ { url = "https://files.pythonhosted.org/packages/8a/12/36ff1d52be18a16b4700f561852e7afd8df56363a5edcfb04cf26a0e19e0/coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e", size = 246516 },
+ { url = "https://files.pythonhosted.org/packages/43/d0/8e258f6c3a527c1655602f4f576215e055ac704de2d101710a71a2affac2/coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9", size = 247783 },
+ { url = "https://files.pythonhosted.org/packages/a9/0d/1e4a48d289429d38aae3babdfcadbf35ca36bdcf3efc8f09b550a845bdb5/coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b", size = 210646 },
+ { url = "https://files.pythonhosted.org/packages/26/74/b0729f196f328ac55e42b1e22ec2f16d8bcafe4b8158a26ec9f1cdd1d93e/coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611", size = 211815 },
+]
+
+[[package]]
+name = "cssselect"
+version = "1.2.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d1/91/d51202cc41fbfca7fa332f43a5adac4b253962588c7cc5a54824b019081c/cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc", size = 41423 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/06/a9/2da08717a6862c48f1d61ef957a7bba171e7eefa6c0aa0ceb96a140c2a6b/cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e", size = 18687 },
+]
+
+[[package]]
+name = "datetime"
+version = "5.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pytz" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2f/66/e284b9978fede35185e5d18fb3ae855b8f573d8c90a56de5f6d03e8ef99e/DateTime-5.5.tar.gz", hash = "sha256:21ec6331f87a7fcb57bd7c59e8a68bfffe6fcbf5acdbbc7b356d6a9a020191d3", size = 63671 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f3/78/8e382b8cb4346119e2e04270b6eb4a01c5ee70b47a8a0244ecdb157204f7/DateTime-5.5-py3-none-any.whl", hash = "sha256:0abf6c51cb4ba7cee775ca46ccc727f3afdde463be28dbbe8803631fefd4a120", size = 52649 },
+]
+
+[[package]]
+name = "decorator"
+version = "5.1.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", size = 35016 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 },
+]
+
+[[package]]
+name = "diazo"
+version = "2.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "cssselect" },
+ { name = "lxml" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0f/0a/8fe739b2e62f0ab1d70e2e3ced665feb827b3ecd923ff9d74fc66f306228/diazo-2.0.3.tar.gz", hash = "sha256:9825e30e7789da8a14436ee642470c62440a9215d329078beb68b12ff6e3aa2e", size = 381166 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/af/527631d1cba3a46bb595147140f8208bd4f948f87a429a3576881a982661/diazo-2.0.3-py3-none-any.whl", hash = "sha256:ebe64ad59208867b8efd4666bb27c67fcc5ee72047a03177f6cf810db3f39f9a", size = 309132 },
+]
+
+[[package]]
+name = "documenttemplate"
+version = "4.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "extensionclass" },
+ { name = "restrictedpython" },
+ { name = "roman" },
+ { name = "zexceptions" },
+ { name = "zope-sequencesort" },
+ { name = "zope-structuredtext" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0b/37/6ddc9ff06cc16a402e5aa8908b99f212dc429507e9e78a457d95448c5083/DocumentTemplate-4.6.tar.gz", hash = "sha256:3b67e42036c7f725f9ab1d66010c7c1406dee4a55110bbaf0c1c643a1dacddb0", size = 70141 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/29/34/71e07eeac40f191d5a152f2704d2150d252c8ae0f0fb5cd75451d89c1347/DocumentTemplate-4.6-py3-none-any.whl", hash = "sha256:4e7b592857c9d6c880b5c664503cb270c3a6d44eabf48ecc468aeb0589fc4477", size = 87021 },
+]
+
+[[package]]
+name = "docutils"
+version = "0.21.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 },
+]
+
+[[package]]
+name = "extensionclass"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/2b/01/08bfef7c8fe8d611f8fa8760985a5f3abf6b14d7da6341418f12c0f34dd3/extensionclass-6.0.tar.gz", hash = "sha256:e36c9863f268b812811d783e4274ec369d9e152fc9fe6ecf7396a0cf8d06b09f", size = 35475 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0a/b3/7e222d223a464b51c1fb01224815c5df321c1d88c3b012504a8dfaa3d1b3/ExtensionClass-6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:774ec90e650628ea5a5542517682187f0f3c294f1689753b20c4040b2859227a", size = 48964 },
+ { url = "https://files.pythonhosted.org/packages/45/f7/e2a88f352203bb91f2ae7b1f685624f5cdd88af62d7890e5a4402361a39b/ExtensionClass-6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5cba5c8ccbf1549a78f76292fdbdc8ea5f18032cadb92e611ac6a2ded1d3befa", size = 50226 },
+ { url = "https://files.pythonhosted.org/packages/aa/ed/2cdd8b3f98711d83879ef910f980a2c66f3a0b8a6942bbf817c63abe1246/ExtensionClass-6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b866fe0e56f2510e02e10d7d64fa540e3f0c8317828c2713ab0e4cd378f53985", size = 97374 },
+ { url = "https://files.pythonhosted.org/packages/57/e8/bc9c08e99fb90ee53ce374a03fe9183a2d238fac1fbf3714addf80211270/ExtensionClass-6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:886b3bbb3c7775e0c25292350e3b2c9aaa1f5628d3127f734f0f5fee40f475e9", size = 90966 },
+ { url = "https://files.pythonhosted.org/packages/20/63/f631a5f89e133c4f6fb2d213b3ab9c7a781123f2e0853836e02fc79f8c67/ExtensionClass-6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83333de0e1fe7960aa63eaa21149331909c6bc668d85cb9643c866bde3cb3518", size = 95367 },
+ { url = "https://files.pythonhosted.org/packages/b9/1e/20483deceef6b162a6009c11d78f0fd35cb4ddee42a797af576b6eb24399/ExtensionClass-6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffe6a5e4491c5e4893a91485cc41ffec71410b9fc2d6eeee5a580003b69dbed2", size = 58811 },
+ { url = "https://files.pythonhosted.org/packages/28/79/d866f7e440369130fe7a1f873f30d7374583d2a57795ade70284656d5ba1/ExtensionClass-6.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:eeff257102bb944144ba54c4011c27b72f180fbc117cc790c1c6fd44e460b12c", size = 48973 },
+ { url = "https://files.pythonhosted.org/packages/a0/ca/f82c2bb905631b369db361f7237f1ea81b7c3e194effd7fbf237681fc1ef/ExtensionClass-6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:76960f235960edff3ded6b57dc11f8e136d13468c4b79ac85f74e5aa737bf344", size = 50238 },
+ { url = "https://files.pythonhosted.org/packages/51/c1/ca30c41afe35a79f39a42d2e88558f07117630a6964f87d477a4d8bcdc4e/ExtensionClass-6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e654f559d4cc10dd70ae5c580429db43fc078e10cfd7c82dbe5fb2029cba504", size = 97341 },
+ { url = "https://files.pythonhosted.org/packages/6c/e9/2d4f1693bcf385e5c12092b031dbcdf33469a194efd5426c7875e47b52cc/ExtensionClass-6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e707b894d844ddefdc35f9a13d7a9fcb6104c5cb1e2af89d9b7db43843c2a72", size = 90963 },
+ { url = "https://files.pythonhosted.org/packages/64/50/297b1cd9c6285d530d3e94ea743242e7e28bd1a08c69c5ae88ea57b51b32/ExtensionClass-6.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9b1647fecc999080c9e43316d427c37e08db897abb05cd99a8d5bc19c7a4ff", size = 95292 },
+ { url = "https://files.pythonhosted.org/packages/d3/c1/b52f877c582470443f8155af8b3a24fd09ca0211828df9ca1ccc0f655e93/ExtensionClass-6.0-cp313-cp313-win_amd64.whl", hash = "sha256:663de162eb5243f0277314a7f9952bcf61f6497e2fba42a7efadc41028edafca", size = 58825 },
+]
+
+[[package]]
+name = "feedparser"
+version = "6.0.11"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "sgmllib3k" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ff/aa/7af346ebeb42a76bf108027fe7f3328bb4e57a3a96e53e21fd9ef9dd6dd0/feedparser-6.0.11.tar.gz", hash = "sha256:c9d0407b64c6f2a065d0ebb292c2b35c01050cc0dc33757461aaabdc4c4184d5", size = 286197 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7c/d4/8c31aad9cc18f451c49f7f9cfb5799dadffc88177f7917bc90a66459b1d7/feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45", size = 81343 },
+]
+
+[[package]]
+name = "five-customerize"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "plone-portlets" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-componentvocabulary" },
+ { name = "zope-dottedname" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-schema" },
+ { name = "zope-traversing" },
+ { name = "zope-viewlet" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/7a/0b/de7649753a18511ed110b49b0fd3ce61dd3133ee8ab1e70766caedf53054/five.customerize-3.0.0.tar.gz", hash = "sha256:ae132a87fdbbc613428ff00375f3d5a057c72f076fe2fe01d8bd173a031921ac", size = 20019 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/30/c2/e2450d9af363ae09fb8e857911797650a0ee978b49782338383d22b27b0d/five.customerize-3.0.0-py3-none-any.whl", hash = "sha256:ad8948b41532678bb9b75ee9e7e6a7be1c7ed985454c8fdd2a0d38e6eb5d3d7f", size = 20831 },
+]
+
+[[package]]
+name = "five-intid"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "five-localsitemanager" },
+ { name = "persistent" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zodb" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-intid" },
+ { name = "zope-keyreference" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/59/4b/21e1f39f90c9630a1212c599588ea25656e6936d209bc914a1f12808c327/five_intid-2.0.1.tar.gz", hash = "sha256:f353fdeed5e53a17a7f381dc814b5c6ba0355170ca98078e73ed37a7210c4b76", size = 28000 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b3/f7/b6a31be52c5c7877d719b764981cf9a7cbbf5776017394f7db1edc01b98d/five_intid-2.0.1-py3-none-any.whl", hash = "sha256:aace4930074926550c51841f1a509c630877ba7ccfe79fb739b72c4b2ce215f6", size = 22509 },
+]
+
+[[package]]
+name = "five-localsitemanager"
+version = "4.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+ { name = "zope-site" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/bc/c9/b43fc6beb19de76a4e665cdc480d9e35a2b75b0e36c339979b9290abbf76/five.localsitemanager-4.0.tar.gz", hash = "sha256:af2da5340c5dc011689b3236160f63faf765b53aa3f1f816b95b954e0a3f5c53", size = 20169 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/99/e8/15f1ad1b722220a3e07440e6709d9a4280c920016bdb989b5050f6471bb3/five.localsitemanager-4.0-py3-none-any.whl", hash = "sha256:74fab4e7ec39377f3f9f5803ce4dd6cededa4999a2e8715e8247411068c087aa", size = 19421 },
+]
+
+[[package]]
+name = "furl"
+version = "2.1.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "orderedmultidict" },
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2a/0a/31a43d63d25f045b88fe7d3267e9ec3ce3820572205a9342c1cdf2ad2ca3/furl-2.1.3.tar.gz", hash = "sha256:5a6188fe2666c484a12159c18be97a1977a71d632ef5bb867ef15f54af39cc4e", size = 44223 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/41/ef/a572e03144d18842c480bd25165ec50ddc20b1744b2aeaaae4408a281f6f/furl-2.1.3-py2.py3-none-any.whl", hash = "sha256:9ab425062c4217f9802508e45feb4a83e54324273ac4b202f1850363309666c0", size = 20880 },
+]
+
+[[package]]
+name = "grpcio"
+version = "1.70.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/69/e1/4b21b5017c33f3600dcc32b802bb48fe44a4d36d6c066f52650c7c2690fa/grpcio-1.70.0.tar.gz", hash = "sha256:8d1584a68d5922330025881e63a6c1b54cc8117291d382e4fa69339b6d914c56", size = 12788932 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/4c/a4/ddbda79dd176211b518f0f3795af78b38727a31ad32bc149d6a7b910a731/grpcio-1.70.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:ef4c14508299b1406c32bdbb9fb7b47612ab979b04cf2b27686ea31882387cff", size = 5198135 },
+ { url = "https://files.pythonhosted.org/packages/30/5c/60eb8a063ea4cb8d7670af8fac3f2033230fc4b75f62669d67c66ac4e4b0/grpcio-1.70.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:aa47688a65643afd8b166928a1da6247d3f46a2784d301e48ca1cc394d2ffb40", size = 11447529 },
+ { url = "https://files.pythonhosted.org/packages/fb/b9/1bf8ab66729f13b44e8f42c9de56417d3ee6ab2929591cfee78dce749b57/grpcio-1.70.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:880bfb43b1bb8905701b926274eafce5c70a105bc6b99e25f62e98ad59cb278e", size = 5664484 },
+ { url = "https://files.pythonhosted.org/packages/d1/06/2f377d6906289bee066d96e9bdb91e5e96d605d173df9bb9856095cccb57/grpcio-1.70.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e654c4b17d07eab259d392e12b149c3a134ec52b11ecdc6a515b39aceeec898", size = 6303739 },
+ { url = "https://files.pythonhosted.org/packages/ae/50/64c94cfc4db8d9ed07da71427a936b5a2bd2b27c66269b42fbda82c7c7a4/grpcio-1.70.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2394e3381071045a706ee2eeb6e08962dd87e8999b90ac15c55f56fa5a8c9597", size = 5910417 },
+ { url = "https://files.pythonhosted.org/packages/53/89/8795dfc3db4389c15554eb1765e14cba8b4c88cc80ff828d02f5572965af/grpcio-1.70.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b3c76701428d2df01964bc6479422f20e62fcbc0a37d82ebd58050b86926ef8c", size = 6626797 },
+ { url = "https://files.pythonhosted.org/packages/9c/b2/6a97ac91042a2c59d18244c479ee3894e7fb6f8c3a90619bb5a7757fa30c/grpcio-1.70.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac073fe1c4cd856ebcf49e9ed6240f4f84d7a4e6ee95baa5d66ea05d3dd0df7f", size = 6190055 },
+ { url = "https://files.pythonhosted.org/packages/86/2b/28db55c8c4d156053a8c6f4683e559cd0a6636f55a860f87afba1ac49a51/grpcio-1.70.0-cp312-cp312-win32.whl", hash = "sha256:cd24d2d9d380fbbee7a5ac86afe9787813f285e684b0271599f95a51bce33528", size = 3600214 },
+ { url = "https://files.pythonhosted.org/packages/17/c3/a7a225645a965029ed432e5b5e9ed959a574e62100afab553eef58be0e37/grpcio-1.70.0-cp312-cp312-win_amd64.whl", hash = "sha256:0495c86a55a04a874c7627fd33e5beaee771917d92c0e6d9d797628ac40e7655", size = 4292538 },
+ { url = "https://files.pythonhosted.org/packages/68/38/66d0f32f88feaf7d83f8559cd87d899c970f91b1b8a8819b58226de0a496/grpcio-1.70.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:aa573896aeb7d7ce10b1fa425ba263e8dddd83d71530d1322fd3a16f31257b4a", size = 5199218 },
+ { url = "https://files.pythonhosted.org/packages/c1/96/947df763a0b18efb5cc6c2ae348e56d97ca520dc5300c01617b234410173/grpcio-1.70.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:d405b005018fd516c9ac529f4b4122342f60ec1cee181788249372524e6db429", size = 11445983 },
+ { url = "https://files.pythonhosted.org/packages/fd/5b/f3d4b063e51b2454bedb828e41f3485800889a3609c49e60f2296cc8b8e5/grpcio-1.70.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f32090238b720eb585248654db8e3afc87b48d26ac423c8dde8334a232ff53c9", size = 5663954 },
+ { url = "https://files.pythonhosted.org/packages/bd/0b/dab54365fcedf63e9f358c1431885478e77d6f190d65668936b12dd38057/grpcio-1.70.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa089a734f24ee5f6880c83d043e4f46bf812fcea5181dcb3a572db1e79e01c", size = 6304323 },
+ { url = "https://files.pythonhosted.org/packages/76/a8/8f965a7171ddd336ce32946e22954aa1bbc6f23f095e15dadaa70604ba20/grpcio-1.70.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19375f0300b96c0117aca118d400e76fede6db6e91f3c34b7b035822e06c35f", size = 5910939 },
+ { url = "https://files.pythonhosted.org/packages/1b/05/0bbf68be8b17d1ed6f178435a3c0c12e665a1e6054470a64ce3cb7896596/grpcio-1.70.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:7c73c42102e4a5ec76608d9b60227d917cea46dff4d11d372f64cbeb56d259d0", size = 6631405 },
+ { url = "https://files.pythonhosted.org/packages/79/6a/5df64b6df405a1ed1482cb6c10044b06ec47fd28e87c2232dbcf435ecb33/grpcio-1.70.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0a5c78d5198a1f0aa60006cd6eb1c912b4a1520b6a3968e677dbcba215fabb40", size = 6190982 },
+ { url = "https://files.pythonhosted.org/packages/42/aa/aeaac87737e6d25d1048c53b8ec408c056d3ed0c922e7c5efad65384250c/grpcio-1.70.0-cp313-cp313-win32.whl", hash = "sha256:fe9dbd916df3b60e865258a8c72ac98f3ac9e2a9542dcb72b7a34d236242a5ce", size = 3598359 },
+ { url = "https://files.pythonhosted.org/packages/1f/79/8edd2442d2de1431b4a3de84ef91c37002f12de0f9b577fb07b452989dbc/grpcio-1.70.0-cp313-cp313-win_amd64.whl", hash = "sha256:4119fed8abb7ff6c32e3d2255301e59c316c22d31ab812b3fbcbaf3d0d87cc68", size = 4293938 },
+]
+
+[[package]]
+name = "grpcio-tools"
+version = "1.70.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "grpcio" },
+ { name = "protobuf" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c1/fe/3adf1035c1f9e9243516530beae67e197f2acc17562ec75f03a0ba77fc55/grpcio_tools-1.70.0.tar.gz", hash = "sha256:e578fee7c1c213c8e471750d92631d00f178a15479fb2cb3b939a07fc125ccd3", size = 5323149 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/58/8d/21f3f0c6e8ddc7ffd82873a6ff767a568a3384043adc034c49fd72020884/grpcio_tools-1.70.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:ec5d6932c3173d7618267b3b3fd77b9243949c5ec04302b7338386d4f8544e0b", size = 2380552 },
+ { url = "https://files.pythonhosted.org/packages/e1/10/def56ecb8e139a96aae9d408d891f32f24a066c57179ce5f78e7edf70a35/grpcio_tools-1.70.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:f22852da12f53b02a3bdb29d0c32fcabab9c7c8f901389acffec8461083f110d", size = 5956826 },
+ { url = "https://files.pythonhosted.org/packages/63/5e/f10375b90b7dc14d1b5095797d4f79b34e584fbc9bda06e093ad316a96dd/grpcio_tools-1.70.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:7d45067e6efd20881e98a0e1d7edd7f207b1625ad7113321becbfe0a6ebee46c", size = 2335835 },
+ { url = "https://files.pythonhosted.org/packages/ec/33/d770fbdf824edfc0f9297be046d4d48fbc81b2dbf802827ade65110f0a47/grpcio_tools-1.70.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3020c97f03b30eee3c26aa2a55fbe003f1729c6f879a378507c2c78524db7c12", size = 2729501 },
+ { url = "https://files.pythonhosted.org/packages/e2/fb/8442f386fa71056abe7ebbc153eaac8cbe32875ed659a641ca526ab9f341/grpcio_tools-1.70.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7fd472fce3b33bdf7fbc24d40da7ab10d7a088bcaf59c37433c2c57330fbcb6", size = 2462824 },
+ { url = "https://files.pythonhosted.org/packages/46/4e/1703d2586663078613baed553de052e029b3d7fe311e90d3f023c85e612a/grpcio_tools-1.70.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3875543d74ce1a698a11f498f83795216ce929cb29afa5fac15672c7ba1d6dd2", size = 3340759 },
+ { url = "https://files.pythonhosted.org/packages/59/d9/f61e427b0e1d7305396dacea65d1e0612eb2bc66b02328ef6bde117624fb/grpcio_tools-1.70.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a130c24d617a3a57369da784080dfa8848444d41b7ae1250abc06e72e706a8d9", size = 2944463 },
+ { url = "https://files.pythonhosted.org/packages/8d/8f/8f6f511ad90e12d7c2f396ad9efe46019c0a77a5f5f69e46998c834405e4/grpcio_tools-1.70.0-cp312-cp312-win32.whl", hash = "sha256:8eae17c920d14e2e451dbb18f5d8148f884e10228061941b33faa8fceee86e73", size = 946776 },
+ { url = "https://files.pythonhosted.org/packages/83/0f/aff5d01ce9ae94ed02b79e033b0c469e560221340c09120270109de4986a/grpcio_tools-1.70.0-cp312-cp312-win_amd64.whl", hash = "sha256:99caa530242a0a832d8b6a6ab94b190c9b449d3e237f953911b4d56207569436", size = 1118594 },
+ { url = "https://files.pythonhosted.org/packages/49/2a/bf442acb748b2a53281e5e7cc3fa36c25ae99436cd2f2cfe684096d4c39f/grpcio_tools-1.70.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:f024688d04e7a9429489ed695b85628075c3c6d655198ba3c6ccbd1d8b7c333b", size = 2380142 },
+ { url = "https://files.pythonhosted.org/packages/dc/a2/984dabaf1cdc41e267acdd37232026ede28f55bc6f9e932907bcbbb46773/grpcio_tools-1.70.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:1fa9a81621d7178498dedcf94eb8f276a7594327faf3dd5fd1935ce2819a2bdb", size = 5955907 },
+ { url = "https://files.pythonhosted.org/packages/cd/78/ebefc32418be93828b46eca5952ef1cb0400b33883bc20c22b1fc2a51f61/grpcio_tools-1.70.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c6da2585c0950cdb650df1ff6d85b3fe31e22f8370b9ee11f8fe641d5b4bf096", size = 2335428 },
+ { url = "https://files.pythonhosted.org/packages/a0/f8/5d4b58dc846bf28b8b9abf07f5d091eb078fc4f01184adb3b374cf5119a4/grpcio_tools-1.70.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70234b592af17050ec30cf35894790cef52aeae87639efe6db854a7fa783cc8c", size = 2728481 },
+ { url = "https://files.pythonhosted.org/packages/b0/28/46833d415b2c2e3e0f36763c528da48785c94580240684e56410abd08aa0/grpcio_tools-1.70.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c021b040d0a9f5bb96a725c4d2b95008aad127d6bed124a7bbe854973014f5b", size = 2462401 },
+ { url = "https://files.pythonhosted.org/packages/fa/8a/c771a09aea58275106e08e7dd37470c6e8555dfcea9a7b44d1c5adc80370/grpcio_tools-1.70.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:114a42e566e5b16a47e98f7910a6c0074b37e2d1faacaae13222e463d0d0d43c", size = 3340068 },
+ { url = "https://files.pythonhosted.org/packages/3a/be/e3dfa73435c633859c4a045c299105e99a6c6a41cda524148bf9c8d4dc99/grpcio_tools-1.70.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:4cae365d7e3ba297256216a9a256458b286f75c64603f017972b3ad1ee374437", size = 2944317 },
+ { url = "https://files.pythonhosted.org/packages/b6/bd/e30fb2b0ce2c0c48caf994b1ebedb56fc7103e26062dd31a41ad1e528eb7/grpcio_tools-1.70.0-cp313-cp313-win32.whl", hash = "sha256:ae139a8d3ddd8353f62af3af018e99ebcd2f4a237bd319cb4b6f58dd608aaa54", size = 946136 },
+ { url = "https://files.pythonhosted.org/packages/0f/8a/92aba852bbe2ddf3e44c354b4162b3cf350b810523ffb2d0e5937bd3f249/grpcio_tools-1.70.0-cp313-cp313-win_amd64.whl", hash = "sha256:04bf30c0eb2741defe3ab6e0a6102b022d69cfd39d68fab9b954993ceca8d346", size = 1118147 },
+]
+
+[[package]]
+name = "gunicorn"
+version = "23.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "packaging" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/34/72/9614c465dc206155d93eff0ca20d42e1e35afc533971379482de953521a4/gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec", size = 375031 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/7d/6dac2a6e1eba33ee43f318edbed4ff29151a49b5d37f080aad1e6469bca4/gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d", size = 85029 },
+]
+
+[[package]]
+name = "h11"
+version = "0.14.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
+]
+
+[[package]]
+name = "hatchling"
+version = "1.27.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "packaging" },
+ { name = "pathspec" },
+ { name = "pluggy" },
+ { name = "trove-classifiers" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/8f/8a/cc1debe3514da292094f1c3a700e4ca25442489731ef7c0814358816bb03/hatchling-1.27.0.tar.gz", hash = "sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6", size = 54983 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/08/e7/ae38d7a6dfba0533684e0b2136817d667588ae3ec984c1a4e5df5eb88482/hatchling-1.27.0-py3-none-any.whl", hash = "sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b", size = 75794 },
+]
+
+[[package]]
+name = "horse-with-no-namespace"
+version = "20250408.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e6/66/681ab7f36264b8b287c9900f7382ce0539a0c139c609a63befd84c1e58f2/horse_with_no_namespace-20250408.0.tar.gz", hash = "sha256:d09810685faf6c4ffcc20f22b0ff320fe267fb75bd46ebfe7dc86b64e0a04b1d", size = 4294 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/87/c8/09ded92d5fbf4c6c0948a16869090f98608a4a2913ef569a81f175af433c/horse_with_no_namespace-20250408.0-py3-none-any.whl", hash = "sha256:0f7913947abbc4c7e9fac015d8b2a14b5fc69cfa0d3665071cf6c94670e870bc", size = 4916 },
+]
+
+[[package]]
+name = "icalendar"
+version = "6.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "python-dateutil" },
+ { name = "tzdata" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fd/b3/8fcd017f8fbaf5c3b8cd1e21dcc3f12158ce08c577b426c3c8eb21373656/icalendar-6.1.1.tar.gz", hash = "sha256:2c44355a8f006de5ae73fa3f022a1cbe2a0de6b1607ce8879739eb887c4f3471", size = 145256 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/cd/a1656e6db3cbb31335d1e62bb94733ad3744d51c63103196d684ed94fa27/icalendar-6.1.1-py3-none-any.whl", hash = "sha256:accf3a4be9a1f89bad00e0bf14103b02cd9b02dcb9b4258eb717f39d24cf58e9", size = 200629 },
+]
+
+[[package]]
+name = "idna"
+version = "3.10"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
+]
+
+[[package]]
+name = "iniconfig"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
+]
+
+[[package]]
+name = "jsonschema"
+version = "4.23.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+ { name = "jsonschema-specifications" },
+ { name = "referencing" },
+ { name = "rpds-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 },
+]
+
+[[package]]
+name = "jsonschema-specifications"
+version = "2024.10.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "referencing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 },
+]
+
+[[package]]
+name = "legacy-cgi"
+version = "2.6.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ad/2e/e1860989bc6cfdecba66db37f2f783636b97a1248ac25fbe864b6e931c22/legacy_cgi-2.6.2.tar.gz", hash = "sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f", size = 24794 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/4c/cd/54d1fd92d7f6aca9523d8583052e00b273bdfe28aa7fd54a3a5759dab05e/legacy_cgi-2.6.2-py3-none-any.whl", hash = "sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff", size = 19572 },
+]
+
+[[package]]
+name = "lxml"
+version = "5.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e7/6b/20c3a4b24751377aaa6307eb230b66701024012c29dd374999cc92983269/lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f", size = 3679318 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/eb/6d/d1f1c5e40c64bf62afd7a3f9b34ce18a586a1cccbf71e783cd0a6d8e8971/lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859", size = 8171753 },
+ { url = "https://files.pythonhosted.org/packages/bd/83/26b1864921869784355459f374896dcf8b44d4af3b15d7697e9156cb2de9/lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e", size = 4441955 },
+ { url = "https://files.pythonhosted.org/packages/e0/d2/e9bff9fb359226c25cda3538f664f54f2804f4b37b0d7c944639e1a51f69/lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f", size = 5050778 },
+ { url = "https://files.pythonhosted.org/packages/88/69/6972bfafa8cd3ddc8562b126dd607011e218e17be313a8b1b9cc5a0ee876/lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e", size = 4748628 },
+ { url = "https://files.pythonhosted.org/packages/5d/ea/a6523c7c7f6dc755a6eed3d2f6d6646617cad4d3d6d8ce4ed71bfd2362c8/lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179", size = 5322215 },
+ { url = "https://files.pythonhosted.org/packages/99/37/396fbd24a70f62b31d988e4500f2068c7f3fd399d2fd45257d13eab51a6f/lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a", size = 4813963 },
+ { url = "https://files.pythonhosted.org/packages/09/91/e6136f17459a11ce1757df864b213efbeab7adcb2efa63efb1b846ab6723/lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3", size = 4923353 },
+ { url = "https://files.pythonhosted.org/packages/1d/7c/2eeecf87c9a1fca4f84f991067c693e67340f2b7127fc3eca8fa29d75ee3/lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1", size = 4740541 },
+ { url = "https://files.pythonhosted.org/packages/3b/ed/4c38ba58defca84f5f0d0ac2480fdcd99fc7ae4b28fc417c93640a6949ae/lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d", size = 5346504 },
+ { url = "https://files.pythonhosted.org/packages/a5/22/bbd3995437e5745cb4c2b5d89088d70ab19d4feabf8a27a24cecb9745464/lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c", size = 4898077 },
+ { url = "https://files.pythonhosted.org/packages/0a/6e/94537acfb5b8f18235d13186d247bca478fea5e87d224644e0fe907df976/lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99", size = 4946543 },
+ { url = "https://files.pythonhosted.org/packages/8d/e8/4b15df533fe8e8d53363b23a41df9be907330e1fa28c7ca36893fad338ee/lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff", size = 4816841 },
+ { url = "https://files.pythonhosted.org/packages/1a/e7/03f390ea37d1acda50bc538feb5b2bda6745b25731e4e76ab48fae7106bf/lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a", size = 5417341 },
+ { url = "https://files.pythonhosted.org/packages/ea/99/d1133ab4c250da85a883c3b60249d3d3e7c64f24faff494cf0fd23f91e80/lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8", size = 5327539 },
+ { url = "https://files.pythonhosted.org/packages/7d/ed/e6276c8d9668028213df01f598f385b05b55a4e1b4662ee12ef05dab35aa/lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d", size = 5012542 },
+ { url = "https://files.pythonhosted.org/packages/36/88/684d4e800f5aa28df2a991a6a622783fb73cf0e46235cfa690f9776f032e/lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30", size = 3486454 },
+ { url = "https://files.pythonhosted.org/packages/fc/82/ace5a5676051e60355bd8fb945df7b1ba4f4fb8447f2010fb816bfd57724/lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f", size = 3816857 },
+ { url = "https://files.pythonhosted.org/packages/94/6a/42141e4d373903bfea6f8e94b2f554d05506dfda522ada5343c651410dc8/lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a", size = 8156284 },
+ { url = "https://files.pythonhosted.org/packages/91/5e/fa097f0f7d8b3d113fb7312c6308af702f2667f22644441715be961f2c7e/lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd", size = 4432407 },
+ { url = "https://files.pythonhosted.org/packages/2d/a1/b901988aa6d4ff937f2e5cfc114e4ec561901ff00660c3e56713642728da/lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51", size = 5048331 },
+ { url = "https://files.pythonhosted.org/packages/30/0f/b2a54f48e52de578b71bbe2a2f8160672a8a5e103df3a78da53907e8c7ed/lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b", size = 4744835 },
+ { url = "https://files.pythonhosted.org/packages/82/9d/b000c15538b60934589e83826ecbc437a1586488d7c13f8ee5ff1f79a9b8/lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002", size = 5316649 },
+ { url = "https://files.pythonhosted.org/packages/e3/ee/ffbb9eaff5e541922611d2c56b175c45893d1c0b8b11e5a497708a6a3b3b/lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4", size = 4812046 },
+ { url = "https://files.pythonhosted.org/packages/15/ff/7ff89d567485c7b943cdac316087f16b2399a8b997007ed352a1248397e5/lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492", size = 4918597 },
+ { url = "https://files.pythonhosted.org/packages/c6/a3/535b6ed8c048412ff51268bdf4bf1cf052a37aa7e31d2e6518038a883b29/lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3", size = 4738071 },
+ { url = "https://files.pythonhosted.org/packages/7a/8f/cbbfa59cb4d4fd677fe183725a76d8c956495d7a3c7f111ab8f5e13d2e83/lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4", size = 5342213 },
+ { url = "https://files.pythonhosted.org/packages/5c/fb/db4c10dd9958d4b52e34d1d1f7c1f434422aeaf6ae2bbaaff2264351d944/lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367", size = 4893749 },
+ { url = "https://files.pythonhosted.org/packages/f2/38/bb4581c143957c47740de18a3281a0cab7722390a77cc6e610e8ebf2d736/lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832", size = 4945901 },
+ { url = "https://files.pythonhosted.org/packages/fc/d5/18b7de4960c731e98037bd48fa9f8e6e8f2558e6fbca4303d9b14d21ef3b/lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff", size = 4815447 },
+ { url = "https://files.pythonhosted.org/packages/97/a8/cd51ceaad6eb849246559a8ef60ae55065a3df550fc5fcd27014361c1bab/lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd", size = 5411186 },
+ { url = "https://files.pythonhosted.org/packages/89/c3/1e3dabab519481ed7b1fdcba21dcfb8832f57000733ef0e71cf6d09a5e03/lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb", size = 5324481 },
+ { url = "https://files.pythonhosted.org/packages/b6/17/71e9984cf0570cd202ac0a1c9ed5c1b8889b0fc8dc736f5ef0ffb181c284/lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b", size = 5011053 },
+ { url = "https://files.pythonhosted.org/packages/69/68/9f7e6d3312a91e30829368c2b3217e750adef12a6f8eb10498249f4e8d72/lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957", size = 3485634 },
+ { url = "https://files.pythonhosted.org/packages/7d/db/214290d58ad68c587bd5d6af3d34e56830438733d0d0856c0275fde43652/lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d", size = 3814417 },
+]
+
+[package.optional-dependencies]
+cssselect = [
+ { name = "cssselect" },
+]
+
+[[package]]
+name = "lxml-html-clean"
+version = "0.4.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/81/f2/fe319e3c5cb505a361b95d1e0d0d793fe28d4dcc2fc39d3cae9324dc4233/lxml_html_clean-0.4.1.tar.gz", hash = "sha256:40c838bbcf1fc72ba4ce811fbb3135913017b27820d7c16e8bc412ae1d8bc00b", size = 21378 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f7/ba/2af7a60b45bf21375e111c1e2d5d721108d06c80e3d9a3cc1d767afe1731/lxml_html_clean-0.4.1-py3-none-any.whl", hash = "sha256:b704f2757e61d793b1c08bf5ad69e4c0b68d6696f4c3c1429982caf90050bcaf", size = 14114 },
+]
+
+[[package]]
+name = "markdown"
+version = "3.7"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 },
+]
+
+[[package]]
+name = "missing"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "extensionclass" },
+ { name = "zope-deferredimport" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0d/34/eb8410ca60ad89487f0c6dca21c89068a17a323acc67d5c078cd2fb65ff6/Missing-5.0.tar.gz", hash = "sha256:81e53a025e1b31a1311aeec56e35249cd7d7f0c278bef42dc09c6dd893ccb185", size = 8276 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2d/b7/9a84a141b07dc1b0ef4d65b4fa2d2173fef84a64649dc8700b62bcddcc7e/Missing-5.0-py3-none-any.whl", hash = "sha256:482e73d644cb7de8d1ae7f559a787e794d27a42981ee9d770f781cb4ab770920", size = 6026 },
+]
+
+[[package]]
+name = "multimapping"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "extensionclass" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/42/a6/f524bda2338932a27a07aafd474293a9a730ba0abab1278b513b00692991/MultiMapping-5.0.tar.gz", hash = "sha256:f09f06dad4ecfe49ba86f4d8389246dc56c17d03148dd5a18b6e1b2856a4f377", size = 5394 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b0/c3/a23cd25567320bde3410bdb4ab9c0d1c4a29a3d62044e157fe413261b39f/MultiMapping-5.0-py3-none-any.whl", hash = "sha256:ed92471d33c2c2eebd6a10a3f854f4a0930a0d65756212118904f8e202d2703d", size = 4311 },
+]
+
+[[package]]
+name = "multipart"
+version = "1.2.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/df/91/6c93b6a95e6a99ef929a99d019fbf5b5f7fd3368389a0b1ec7ce0a23565b/multipart-1.2.1.tar.gz", hash = "sha256:829b909b67bc1ad1c6d4488fcdc6391c2847842b08323addf5200db88dbe9480", size = 36507 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cc/d1/3598d1e73385baaab427392856f915487db7aa10abadd436f8f2d3e3b0f9/multipart-1.2.1-py3-none-any.whl", hash = "sha256:c03dc203bc2e67f6b46a599467ae0d87cf71d7530504b2c1ff4a9ea21d8b8c8c", size = 13730 },
+]
+
+[[package]]
+name = "mypy"
+version = "1.15.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "mypy-extensions" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981 },
+ { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175 },
+ { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675 },
+ { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020 },
+ { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582 },
+ { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614 },
+ { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592 },
+ { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611 },
+ { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443 },
+ { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541 },
+ { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348 },
+ { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648 },
+ { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777 },
+]
+
+[[package]]
+name = "mypy-extensions"
+version = "1.1.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963 },
+]
+
+[[package]]
+name = "natsort"
+version = "8.4.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 },
+]
+
+[[package]]
+name = "node"
+version = "1.2.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "odict" },
+ { name = "plumber" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-deferredimport" },
+ { name = "zope-deprecation" },
+ { name = "zope-lifecycleevent" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/8c/93/2236fa76a8361d88ce2d0fd2a87961613898aded8b7bd214c19038a7aabe/node-1.2.2.tar.gz", hash = "sha256:4e164c76912c5b11397758ebbd27f032f116b32c306f0a90b235da466e188527", size = 100420 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3c/fa/d84aa48f238ba1cd6d256ebe9b2dbfb5e2b5e2ea968a2f6f650c272dcaf2/node-1.2.2-py3-none-any.whl", hash = "sha256:93884cc7ed36f3b43c3c8a4f3370723b8a5fe4bb3e9a817a693a21ffb44206f4", size = 102775 },
+]
+
+[[package]]
+name = "node-ext-zodb"
+version = "1.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "node" },
+ { name = "setuptools" },
+ { name = "zodb" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/10/7b/6a30e17994d5004dcc6822378bfef3818556e8e859f990ac87cb1d181974/node.ext.zodb-1.6.tar.gz", hash = "sha256:03a14b1e59437a1a347eec2e505dc45122b8ab557b369f260d7348cf913afac1", size = 13258 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/43/eb/29ff611d95f95e0feb7c953a67f323927b33d0c17c4d1a2fe7744bd971fe/node.ext.zodb-1.6-py3-none-any.whl", hash = "sha256:667a580421e10ae23cf4a86598bbaedebaa6f630c228fa3e765799bda4327f79", size = 12613 },
+]
+
+[[package]]
+name = "odict"
+version = "1.9.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/4e/e8/cf1364a64065652d13d40d83ad7c31c12d18e8ae824549c8975f3eaf481a/odict-1.9.0.tar.gz", hash = "sha256:fc4a05c46fd3d574bf9cf89a3e23aa3f1584a246419a1f7365fc36f9f36c2b44", size = 18205 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7c/87/02e04067920b8d88800eddae61edcd8f7db8a06d043ec6abe91201752ec3/odict-1.9.0-py3-none-any.whl", hash = "sha256:6e7ff07552d3c6cddffac565fdc7fd1fef0220b6c68f518128cab40f82114d97", size = 15191 },
+]
+
+[[package]]
+name = "orderedmultidict"
+version = "1.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/53/4e/3823a27d764bb8388711f4cb6f24e58453e92d6928f4163fdb01e3a3789f/orderedmultidict-1.0.1.tar.gz", hash = "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad", size = 20706 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/04/16/5e95c70bda8fe6ea715005c0db8e602400bdba50ae3c72cb380eba551289/orderedmultidict-1.0.1-py2.py3-none-any.whl", hash = "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3", size = 11699 },
+]
+
+[[package]]
+name = "outcome"
+version = "1.3.0.post0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692 },
+]
+
+[[package]]
+name = "overrides"
+version = "7.7.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 },
+]
+
+[[package]]
+name = "packaging"
+version = "24.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
+]
+
+[[package]]
+name = "paste"
+version = "3.10.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d7/1c/6bc9040bf9b4cfc9334f66d2738f952384c106c48882adf6097fed3da966/paste-3.10.1.tar.gz", hash = "sha256:1c3d12065a5e8a7a18c0c7be1653a97cf38cc3e9a5a0c8334a9dd992d3a05e4a", size = 652629 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2e/14/032895c25726a859bf48b8ed68944c3efc7a3decd920533ed929f12f08a1/Paste-3.10.1-py3-none-any.whl", hash = "sha256:995e9994b6a94a2bdd8bd9654fb70ca3946ffab75442468bacf31b4d06481c3d", size = 289253 },
+]
+
+[[package]]
+name = "pastedeploy"
+version = "3.1.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e3/97/0c4a613ec96a54d21daa7e089178263915554320402e89b4e319436a63cb/PasteDeploy-3.1.0.tar.gz", hash = "sha256:9ddbaf152f8095438a9fe81f82c78a6714b92ae8e066bed418b6a7ff6a095a95", size = 37841 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/85/30/cdddd9a88969683a59222a6d61cd6dce923977f2e9f9ffba38e1324149cd/PasteDeploy-3.1.0-py3-none-any.whl", hash = "sha256:76388ad53a661448d436df28c798063108f70e994ddc749540d733cdbd1b38cf", size = 16943 },
+]
+
+[[package]]
+name = "pathspec"
+version = "0.12.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 },
+]
+
+[[package]]
+name = "perfmetrics"
+version = "4.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/bb/26/bd5e2ac556e7eb1a9d3bc82599b21445ca27318a3d1ad891797030f497a1/perfmetrics-4.1.0.tar.gz", hash = "sha256:495e0eee5681961ec8b2fce9eafa372c90919d9a57cbe7ca0fca7b52a89f5519", size = 141935 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e5/47/1eb1519bc8377c9f0bc42d2aee06add7ed56a54dd3a655f05d8815bf6dea/perfmetrics-4.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4ffb0d2ca1fd614bf6832c2fe7c0e3d1a9b8f57215f498206801470c490bcb4d", size = 234181 },
+ { url = "https://files.pythonhosted.org/packages/26/39/bb8e264b9401cadf3647de9de8336ea549131dedc00d40ba8452a0db934e/perfmetrics-4.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fa39cf2406cd0414eb2d11587739daa6a7f684e730b4ed7c47a496e050cf742", size = 442782 },
+ { url = "https://files.pythonhosted.org/packages/e9/fd/d05f36916f91c8378d32506daa063665d525193d0c7c752fccf63529b283/perfmetrics-4.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc80cde10398f52f41491be261cf3361350b4b77ab4ebbdee1b5e85a3628922b", size = 451667 },
+ { url = "https://files.pythonhosted.org/packages/f6/c4/01a78860249fd8a61617a7b669537b063bcbb0d096ff47eced4c9740c577/perfmetrics-4.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74fc996b4bc52f2f502f7a6f29d6d30ad9b3a6338bc99cccb42a96e4b9d5fba4", size = 454321 },
+ { url = "https://files.pythonhosted.org/packages/3e/98/60b9f354c0840af60b26d242557b6428641ef759af02a2c9081dd87534ee/perfmetrics-4.1.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37ee828552f9d5a2e94c525e294aaef2d33a3eef628c452baa81c0ade60f1d63", size = 448245 },
+ { url = "https://files.pythonhosted.org/packages/28/4b/335a30a14f6d0d963ea23cfe5306db69aa2ab61bb59d0d2e8568982a8139/perfmetrics-4.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:937dfbba3ac30aa5aa6040731ec67f7da0af59a6fd5148c68f8f43baa9b0a31c", size = 443041 },
+ { url = "https://files.pythonhosted.org/packages/70/a7/156745db1bf9dbec9489e539cf7c18883d70767b49ff37917f8a2403907c/perfmetrics-4.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:896d8caf7d8f4a6d9ec16fbadd2dd51f7c155d6199b9c638a1bac5987fae3d33", size = 447967 },
+ { url = "https://files.pythonhosted.org/packages/54/b4/650a4cfc7f1991d7a7552a265f113a02d6703333319c34166319c08689df/perfmetrics-4.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:b75d99cccae4e1e92545be602b0450580e4aa1711615169d0cd69d71ae6f0b2c", size = 177659 },
+ { url = "https://files.pythonhosted.org/packages/37/47/763f86ba303ae53c33a1d48d3fa56575897e364e291faf5c6c0499f32a28/perfmetrics-4.1.0-cp313-cp313-macosx_10_9_universal2.whl", hash = "sha256:25bbb8b0e48e4dff888a7871c658c49b071089f26a77c5915fff7280b7e82a88", size = 232933 },
+ { url = "https://files.pythonhosted.org/packages/74/7c/d55cf48f84707eb5f2956092fbb52f4a950b07fa2ce90920575fd8dcf6c9/perfmetrics-4.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4495ff3b889946dc753a6f77eda2d1d7c888c7b349384ae4edd87163462e9bd", size = 439384 },
+ { url = "https://files.pythonhosted.org/packages/90/92/ec611974798040e959862b8bb1ccf1dbfa446fb756ad0d54b4cdb7c24d16/perfmetrics-4.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2d7406e808fec5f980544077dad63382fecab57586db5acf44045c86de2821c", size = 448600 },
+ { url = "https://files.pythonhosted.org/packages/bc/8e/ddbaae41d951a482bf31345e576fde23ba6a1c778b999ab1b31426da5169/perfmetrics-4.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95912530cbf66eed308d754e545c54df354ecc60a09702533796ad60edb9a1d9", size = 451323 },
+ { url = "https://files.pythonhosted.org/packages/82/85/5d425bb92897902d9931029460b4681b5fed9e618b6ac1249f936415d7c7/perfmetrics-4.1.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689c7e587c003aa9f256b684c1709f042e32483debfee87dec7997f50738d02a", size = 444286 },
+ { url = "https://files.pythonhosted.org/packages/5f/50/4c6d60955d477fc992980b811c8d38b1dff50405ff10989fae5809b8aafe/perfmetrics-4.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a31838d0f63b93327d61cfe84ca43ee23a607bf8015c4997697ff846ce7525c7", size = 436899 },
+ { url = "https://files.pythonhosted.org/packages/2b/bf/48eac3831b075dea647de387859929e0ba1efbfdf16cd6241cf22c0e687c/perfmetrics-4.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:bc08822ab37e2393f58407a8d4c5dee99eda328fc0443b08333cca8f65de553b", size = 441863 },
+]
+
+[[package]]
+name = "persistence"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "extensionclass" },
+ { name = "persistent" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/03/7a/f344d4fc124a9df6856099e9fb9db1a7dffec852a44aa1786d5064a3c286/persistence-5.1.tar.gz", hash = "sha256:4877b6a2ffe15d293e5323a0c530d3a8f9abb7ff27e9f409727c749fb057aec5", size = 22113 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/79/4e/52b3b3f36f38471bf8b41cab3744efb7282ab5daa2ffeed87790adbcbca4/Persistence-5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c67d38efc1e23f4d4215ce1c6fac9381388f40a3086d6785ef5e48151c784ca0", size = 15670 },
+ { url = "https://files.pythonhosted.org/packages/0c/2e/dd262d187e5c18297c23843fb1237283850bf8b5adaffb8d811fbada07cc/Persistence-5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:011604dc10a551c6af72676c59578a0fa509fdb2c7911b8149e6808e9d8e951a", size = 16135 },
+ { url = "https://files.pythonhosted.org/packages/f4/91/9f82120b8790df7942a4b96b593f78688962f38f0b8a9d99ac854b548c9b/Persistence-5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4efe8e3a84e3fae2bc0f489a35342fe63008fa2ced72bc24af330a1cd4a0df7", size = 25408 },
+ { url = "https://files.pythonhosted.org/packages/57/21/4c58c196417fe15437aa95017c261ffa128e7ae2cf403175cd225706087a/Persistence-5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8bf53d21aef1d325665c143834e22b828e5117b623bfb599f9db77f365b340bd", size = 24472 },
+ { url = "https://files.pythonhosted.org/packages/09/72/9794a4cfe8f888c5636533e7ca2f87fbbdfbdee45fde99be533dcf870cb5/Persistence-5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea929909ae03f85f7f820372cfe82243449c0eb9b7a962f927901354cb095761", size = 24740 },
+ { url = "https://files.pythonhosted.org/packages/7e/f2/9379abac41a02db35ca2b06a5cfb2efb2b1e3fab2594f238f1270271f238/Persistence-5.1-cp312-cp312-win_amd64.whl", hash = "sha256:2754765f20ab168da0bec39aeb65002f8f4c33a640e8c5b86351bf69adb514dc", size = 19526 },
+ { url = "https://files.pythonhosted.org/packages/ee/de/00e8ac679c1ede6fbbf4b889cbb82aac24440d2969864d96c0f211d58462/Persistence-5.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:90e342493702d659ab4162f52a32296c918a2e24df65a0f4a1d9366da5bdca6f", size = 15676 },
+ { url = "https://files.pythonhosted.org/packages/95/9f/64bf8cdeff71151735af9d23629ac4e6f8e0cd66180cec3717c447aef1ca/Persistence-5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c8359b904530122988e5d8344bebb8f12dd072067ee309b4bf3efc605aa262a2", size = 16138 },
+ { url = "https://files.pythonhosted.org/packages/ca/90/f736dd73ea1a6503843369cb1903120d8281f0bcf2a0c168e350611f8678/Persistence-5.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00a25f662c1b21479564b9714c539f02fbc3d3629cc3a1a6bc8920a99ac8b74", size = 25394 },
+ { url = "https://files.pythonhosted.org/packages/25/da/875cc6d892df468295833b06938cae26fb1c7b5a4aacd29da6f5692a2e75/Persistence-5.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbe9e0710418de09fe5e3eb41453cd8289146184c3cdcb73b72305489a6860d2", size = 24465 },
+ { url = "https://files.pythonhosted.org/packages/d8/e2/135e595620f7f35394ed793075c972d55905fcb8acd6805c3f63bf05b1f5/Persistence-5.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca0d85a3fa40a76f64c4e2327a287f553fb8f1c7afd2966c81b2910679c4e4e4", size = 24705 },
+ { url = "https://files.pythonhosted.org/packages/8c/4b/7189cd407312b27de0d8bb87e8beae2ccb42291958dc518e5029ab89c996/Persistence-5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e49a48d34ca1b2dc8bf1c6cf864017ebd05a879261eff59bdc08e4acbaa2a1d1", size = 19530 },
+]
+
+[[package]]
+name = "persistent"
+version = "6.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "cffi", marker = "platform_python_implementation == 'CPython'" },
+ { name = "zope-deferredimport" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/33/ff/6e576c834287031b2482d17ecdee7541bfc8e514c684c2e2b93599073708/persistent-6.1.tar.gz", hash = "sha256:aa17e6e4849738d080706ebe6c79ec8db0f4ab2c87975f9b34249eaf7a965867", size = 128681 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/22/99/b96ab1f9b6e57a3e74463e34332aa730651729faeef9c88017dfd387a71f/persistent-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8aafc5b8d7bc918997a22ea168a38e06f4343013a8fa4cbc857a9fab251367ad", size = 145151 },
+ { url = "https://files.pythonhosted.org/packages/cc/20/454b68954148f2b3607880b6b5991fea8ca402d8d2dd9aae3c359936667f/persistent-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b15cd9ad8810388b1ae43d52733cafc04307cc9b3af63619eb8164d90ae14d6", size = 147104 },
+ { url = "https://files.pythonhosted.org/packages/93/28/f9772cd88dfe6854c8865e7c61aecaa6a0ad6e668c848968c1cdef31dc0c/persistent-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d626204286f84cfd4feef39387732d18832c76afbcba2bba4eee03b1ae759e8a", size = 240995 },
+ { url = "https://files.pythonhosted.org/packages/8e/55/7095d734ad7e6895d2d474be52afe6643d9d67b4927f76afd8dbef19a112/persistent-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c741c8461f9454828650850fc21687b57801839bb960c080f5823f54cd49fb85", size = 229470 },
+ { url = "https://files.pythonhosted.org/packages/98/d8/f53cca4242e564c4be0e11846c57d8db0b9559fe038866061f02c891460a/persistent-6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2111566a7ac526240e37a4b2363cb9ebe40838369d363950222f15b5482cf944", size = 239330 },
+ { url = "https://files.pythonhosted.org/packages/2c/68/83080646ba4667dace35769879eec358912d2e30e67b9592dcfa6f223339/persistent-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:93b5943db6795f06f85010f9f038dc10ddd03c017dccf5ba87ef22ad6370e11f", size = 128279 },
+ { url = "https://files.pythonhosted.org/packages/78/02/f09f7e3712baa1a097d0994fac9b8656cc111d8f6051eb3ad317ffdbe872/persistent-6.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:ade3bfe8f8583c504368d6cb122cc10cdbd7400bc65504b7d601c51a490b1702", size = 145149 },
+ { url = "https://files.pythonhosted.org/packages/54/51/0ffa0146108722dec0226a7b9e5fa84e4b4f801b0713ce6564c06fd8bc98/persistent-6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f18bf43306bb590e43c97c525000b76cb9ed4478f9bbc10ba9ee817648c9b0a1", size = 147101 },
+ { url = "https://files.pythonhosted.org/packages/0b/10/b131a6fb015ed45e89147b751042c91837bb63173e741b1748e0722d6cb5/persistent-6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c6c2798b565ac1903b7062ef11a61260cd44257ab1e50c9d6819f42d8598e68", size = 240703 },
+ { url = "https://files.pythonhosted.org/packages/b4/07/2229f5784aa54df3a3109baeb20783cc63e773b4710b18851c55c696433a/persistent-6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d14253dc90645d50241d0a7f57e04bffcda009cd6f9a96900b0c4d8071add781", size = 229196 },
+ { url = "https://files.pythonhosted.org/packages/96/90/f86528728293c2604d6b7c9824db259a566d01688269eab52232436b7e76/persistent-6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f262511534adea3157afc606aa93f041e62479cc2f238505eeb202e2f117dc22", size = 238986 },
+ { url = "https://files.pythonhosted.org/packages/dd/f3/0c18a8523d5eeb2d05d6e1b5587b37e55330a245cdfdde82659ebbcdaada/persistent-6.1-cp313-cp313-win_amd64.whl", hash = "sha256:9839c16817fca6eb076137882f652dfdd7ed1e06154ac2b415bfee97f65bbea5", size = 128289 },
+]
+
+[[package]]
+name = "piexif"
+version = "1.1.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/fa/84/a3f25cec7d0922bf60be8000c9739d28d24b6896717f44cc4cfb843b1487/piexif-1.1.3.zip", hash = "sha256:83cb35c606bf3a1ea1a8f0a25cb42cf17e24353fd82e87ae3884e74a302a5f1b", size = 1011134 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2c/d8/6f63147dd73373d051c5eb049ecd841207f898f50a5a1d4378594178f6cf/piexif-1.1.3-py2.py3-none-any.whl", hash = "sha256:3bc435d171720150b81b15d27e05e54b8abbde7b4242cddd81ef160d283108b6", size = 20691 },
+]
+
+[[package]]
+name = "pillow"
+version = "11.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", size = 46737780 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1c/a3/26e606ff0b2daaf120543e537311fa3ae2eb6bf061490e4fea51771540be/pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", size = 3147642 },
+ { url = "https://files.pythonhosted.org/packages/4f/d5/1caabedd8863526a6cfa44ee7a833bd97f945dc1d56824d6d76e11731939/pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", size = 2978999 },
+ { url = "https://files.pythonhosted.org/packages/d9/ff/5a45000826a1aa1ac6874b3ec5a856474821a1b59d838c4f6ce2ee518fe9/pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", size = 4196794 },
+ { url = "https://files.pythonhosted.org/packages/9d/21/84c9f287d17180f26263b5f5c8fb201de0f88b1afddf8a2597a5c9fe787f/pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", size = 4300762 },
+ { url = "https://files.pythonhosted.org/packages/84/39/63fb87cd07cc541438b448b1fed467c4d687ad18aa786a7f8e67b255d1aa/pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9", size = 4210468 },
+ { url = "https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", size = 4381824 },
+ { url = "https://files.pythonhosted.org/packages/31/69/1ef0fb9d2f8d2d114db982b78ca4eeb9db9a29f7477821e160b8c1253f67/pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", size = 4296436 },
+ { url = "https://files.pythonhosted.org/packages/44/ea/dad2818c675c44f6012289a7c4f46068c548768bc6c7f4e8c4ae5bbbc811/pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", size = 4429714 },
+ { url = "https://files.pythonhosted.org/packages/af/3a/da80224a6eb15bba7a0dcb2346e2b686bb9bf98378c0b4353cd88e62b171/pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", size = 2249631 },
+ { url = "https://files.pythonhosted.org/packages/57/97/73f756c338c1d86bb802ee88c3cab015ad7ce4b838f8a24f16b676b1ac7c/pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", size = 2567533 },
+ { url = "https://files.pythonhosted.org/packages/0b/30/2b61876e2722374558b871dfbfcbe4e406626d63f4f6ed92e9c8e24cac37/pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", size = 2254890 },
+ { url = "https://files.pythonhosted.org/packages/63/24/e2e15e392d00fcf4215907465d8ec2a2f23bcec1481a8ebe4ae760459995/pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699", size = 3147300 },
+ { url = "https://files.pythonhosted.org/packages/43/72/92ad4afaa2afc233dc44184adff289c2e77e8cd916b3ddb72ac69495bda3/pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38", size = 2978742 },
+ { url = "https://files.pythonhosted.org/packages/9e/da/c8d69c5bc85d72a8523fe862f05ababdc52c0a755cfe3d362656bb86552b/pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2", size = 4194349 },
+ { url = "https://files.pythonhosted.org/packages/cd/e8/686d0caeed6b998351d57796496a70185376ed9c8ec7d99e1d19ad591fc6/pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2", size = 4298714 },
+ { url = "https://files.pythonhosted.org/packages/ec/da/430015cec620d622f06854be67fd2f6721f52fc17fca8ac34b32e2d60739/pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527", size = 4208514 },
+ { url = "https://files.pythonhosted.org/packages/44/ae/7e4f6662a9b1cb5f92b9cc9cab8321c381ffbee309210940e57432a4063a/pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa", size = 4380055 },
+ { url = "https://files.pythonhosted.org/packages/74/d5/1a807779ac8a0eeed57f2b92a3c32ea1b696e6140c15bd42eaf908a261cd/pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f", size = 4296751 },
+ { url = "https://files.pythonhosted.org/packages/38/8c/5fa3385163ee7080bc13026d59656267daaaaf3c728c233d530e2c2757c8/pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb", size = 4430378 },
+ { url = "https://files.pythonhosted.org/packages/ca/1d/ad9c14811133977ff87035bf426875b93097fb50af747793f013979facdb/pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798", size = 2249588 },
+ { url = "https://files.pythonhosted.org/packages/fb/01/3755ba287dac715e6afdb333cb1f6d69740a7475220b4637b5ce3d78cec2/pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de", size = 2567509 },
+ { url = "https://files.pythonhosted.org/packages/c0/98/2c7d727079b6be1aba82d195767d35fcc2d32204c7a5820f822df5330152/pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84", size = 2254791 },
+ { url = "https://files.pythonhosted.org/packages/eb/38/998b04cc6f474e78b563716b20eecf42a2fa16a84589d23c8898e64b0ffd/pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b", size = 3150854 },
+ { url = "https://files.pythonhosted.org/packages/13/8e/be23a96292113c6cb26b2aa3c8b3681ec62b44ed5c2bd0b258bd59503d3c/pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003", size = 2982369 },
+ { url = "https://files.pythonhosted.org/packages/97/8a/3db4eaabb7a2ae8203cd3a332a005e4aba00067fc514aaaf3e9721be31f1/pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2", size = 4333703 },
+ { url = "https://files.pythonhosted.org/packages/28/ac/629ffc84ff67b9228fe87a97272ab125bbd4dc462745f35f192d37b822f1/pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a", size = 4412550 },
+ { url = "https://files.pythonhosted.org/packages/d6/07/a505921d36bb2df6868806eaf56ef58699c16c388e378b0dcdb6e5b2fb36/pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8", size = 4461038 },
+ { url = "https://files.pythonhosted.org/packages/d6/b9/fb620dd47fc7cc9678af8f8bd8c772034ca4977237049287e99dda360b66/pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8", size = 2253197 },
+ { url = "https://files.pythonhosted.org/packages/df/86/25dde85c06c89d7fc5db17940f07aae0a56ac69aa9ccb5eb0f09798862a8/pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904", size = 2572169 },
+ { url = "https://files.pythonhosted.org/packages/51/85/9c33f2517add612e17f3381aee7c4072779130c634921a756c97bc29fb49/pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", size = 2256828 },
+]
+
+[[package]]
+name = "plone-alterego"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/78/8b/8491a330d13510c81da97485771f261a0bc230526a8c318662db3da3ae74/plone.alterego-2.0.1.tar.gz", hash = "sha256:b59b103df670e6fbe2950df859a70447b9ccd60b86ba87e838efeb11b13a9ec6", size = 14172 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/13/4e/99bb16a38772b09d87663090d4afc954d74d80b43634d38e89857949e6a1/plone.alterego-2.0.1-py3-none-any.whl", hash = "sha256:e161e62d803f3468e86917a0233b29a590b575b21afa6842ef69d783fa08405a", size = 7182 },
+]
+
+[[package]]
+name = "plone-api"
+version = "2.5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "decorator" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-intid" },
+ { name = "plone-app-linkintegrity" },
+ { name = "plone-app-uuid" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-i18n" },
+ { name = "plone-registry" },
+ { name = "plone-uuid" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfplone" },
+ { name = "products-plonepas" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-relationfield" },
+ { name = "zc-relation" },
+ { name = "zope" },
+ { name = "zope-globalrequest" },
+ { name = "zope-intid" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/57/57/88ff9a9271c89eaf9c1e9da0fff7a575e755c661ea4e68d576a55ec85cd6/plone_api-2.5.0.tar.gz", hash = "sha256:49b0965c9b5ac073b9d57f5c98aa97a89f14a0e999ec3178743c10e84c4dceb7", size = 127984 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a6/be/8d26a4efedf40d3ec7886c38c4becb0f9afec0fd1349bd8caa8294936b72/plone_api-2.5.0-py3-none-any.whl", hash = "sha256:4b10a96fbf396dd76f5ed53028b3f87cbbef7993b9abdc9d7de51d94992a3f05", size = 101144 },
+]
+
+[[package]]
+name = "plone-app-caching"
+version = "4.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-registry" },
+ { name = "plone-base" },
+ { name = "plone-cachepurging" },
+ { name = "plone-caching" },
+ { name = "plone-dexterity" },
+ { name = "plone-memoize" },
+ { name = "plone-namedfile" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-transformchain" },
+ { name = "plone-z3cform" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfdynamicviewfti" },
+ { name = "products-cmfplone" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "python-dateutil" },
+ { name = "setuptools" },
+ { name = "z3c-caching" },
+ { name = "z3c-form" },
+ { name = "z3c-zcmlhook" },
+ { name = "zope" },
+ { name = "zope-ramcache" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d8/91/377e9143033e3327bbf803e92d46b09249c84a752b94f43000dbc864a717/plone_app_caching-4.1.0.tar.gz", hash = "sha256:bcbd5fa9144ac5a7ecd5a6d0bdbb5833f63bfbb71cb894625d514d7959ee8053", size = 95442 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3c/dc/129158bf3677d108e947da9c1ecc632cb189ae6c87763c9a46464fa4f073/plone.app.caching-4.1.0-py3-none-any.whl", hash = "sha256:0c3e8cc071b806f9365d3dcd041da3d6a94fe92e217f8fcfbba6a90a336ae339", size = 104030 },
+]
+
+[[package]]
+name = "plone-app-content"
+version = "4.1.9"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "missing" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-querystring" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-folder" },
+ { name = "plone-i18n" },
+ { name = "plone-locking" },
+ { name = "plone-memoize" },
+ { name = "plone-protect" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "products-mimetypesregistry" },
+ { name = "products-portaltransforms" },
+ { name = "products-statusmessages" },
+ { name = "simplejson" },
+ { name = "z3c-form" },
+ { name = "z3c-relationfield" },
+ { name = "zope" },
+ { name = "zope-browsermenu" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/02/ef/782158455bad28b8d9fa8ff22563ed37bbb0a3a83b3ae016e54a373bf0cf/plone_app_content-4.1.9.tar.gz", hash = "sha256:aeb6fa9922c4a5e34528243f25184797449d1711309fcfe61ef235dc6042fb4a", size = 121969 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e7/0b/c414627982868623bc691da1dfe59c8bf6680c52a7b055aa5928f1f52e7b/plone.app.content-4.1.9-py3-none-any.whl", hash = "sha256:76d00b8f716f27d23e8ebcee3f6d5e5136cc74f1411cec09960b6eb4e9cd3777", size = 118942 },
+]
+
+[[package]]
+name = "plone-app-contentlisting"
+version = "3.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-registry" },
+ { name = "plone-rfc822" },
+ { name = "plone-uuid" },
+ { name = "products-mimetypesregistry" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/62/a3/276070785e3fc766bad1d8b067548d18476eb2e3e2142bbfa14600d5b3df/plone.app.contentlisting-3.0.5.tar.gz", hash = "sha256:2dfd9b507bcd7a31620e561e29951d089b953a89c231b6181bab6afc8b59971d", size = 35468 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8b/b1/86aaf023d030a3202d4c10ae4c179d4b5ec59efc26114dc45b5889049f7f/plone.app.contentlisting-3.0.5-py3-none-any.whl", hash = "sha256:b220264820e655edbb08f0f4ea236dc2500e9f11524a782abebc8b8aac5245d7", size = 23314 },
+]
+
+[[package]]
+name = "plone-app-contentmenu"
+version = "3.0.7"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-content" },
+ { name = "plone-base" },
+ { name = "plone-locking" },
+ { name = "plone-memoize" },
+ { name = "plone-portlets" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c0/52/285043d6c99cf803b7ca1fd5ed085860566129da092edbd11b150f803701/plone_app_contentmenu-3.0.7.tar.gz", hash = "sha256:30535ae2eed07b117aeef71fc62d41703964b4946584a844080dd1b8d939c2c1", size = 42706 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/95/17/a9f77edaa94d1dc372ce1b2c38f0074ff8209b6e3e5ea1db5e0356694b87/plone_app_contentmenu-3.0.7-py3-none-any.whl", hash = "sha256:e3679952d772572c104d21eea77758c6e0e5fc3b97fbdd905aa9df4d86254f97", size = 27411 },
+]
+
+[[package]]
+name = "plone-app-contentrules"
+version = "5.0.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "plone-app-contenttypes" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-contentrules" },
+ { name = "plone-memoize" },
+ { name = "plone-stringinterp" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "products-genericsetup" },
+ { name = "products-mailhost" },
+ { name = "products-pluggableauthservice" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/30/c4/eac93115a6ea80388fe74d823729bae4d0db212c4d306db25e215201d021/plone_app_contentrules-5.0.6.tar.gz", hash = "sha256:fb6ca3365aa4b48e0f97cec95bc8884311cc9bb9a3fa2b2bc61f3c97b57499a5", size = 74956 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e5/57/b26265b300435f5236f3fd9d77ed94e9e98045387ffe77c4b294aba9773c/plone.app.contentrules-5.0.6-py3-none-any.whl", hash = "sha256:7ed5e17e885aa0eb89c3e8695a90c6c9539ce0ab235d9819ce7b4a23594b4617", size = 102196 },
+]
+
+[[package]]
+name = "plone-app-contenttypes"
+version = "4.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-contentmenu" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-layout" },
+ { name = "plone-app-linkintegrity" },
+ { name = "plone-app-lockingbehavior" },
+ { name = "plone-app-querystring" },
+ { name = "plone-app-relationfield" },
+ { name = "plone-app-textfield" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-versioningbehavior" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-dexterity" },
+ { name = "plone-event" },
+ { name = "plone-folder" },
+ { name = "plone-indexer" },
+ { name = "plone-memoize" },
+ { name = "plone-namedfile" },
+ { name = "plone-portlets" },
+ { name = "plone-registry" },
+ { name = "plone-rfc822" },
+ { name = "plone-supermodel" },
+ { name = "plone-z3cform" },
+ { name = "products-btreefolder2" },
+ { name = "products-genericsetup" },
+ { name = "products-mimetypesregistry" },
+ { name = "products-portaltransforms" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/18/46/0e04695b4de12d64092418712c953944eaea1a2b73fa17d898401ad6333a/plone_app_contenttypes-4.0.5.tar.gz", hash = "sha256:a3b266695f8ebaa15088832b23ae963c764b17704d1ee06a47d33ab47e70f325", size = 156610 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ce/f2/152315c3ccf4ac622a0a28d1e83b08a07ee464993bf773bb4c3179b3518b/plone_app_contenttypes-4.0.5-py3-none-any.whl", hash = "sha256:0b0fb9f1772c92e8abe015cafcf559ab35d6fb57a0ca9abf7524cffb6df483b4", size = 152486 },
+]
+
+[package.optional-dependencies]
+test = [
+ { name = "lxml" },
+ { name = "plone-app-robotframework", extra = ["debug"] },
+ { name = "plone-app-testing", extra = ["robot"] },
+ { name = "plone-browserlayer" },
+ { name = "plone-testing" },
+ { name = "plone-uuid" },
+ { name = "robotsuite" },
+]
+
+[[package]]
+name = "plone-app-customerize"
+version = "2.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "five-customerize" },
+ { name = "plone-browserlayer" },
+ { name = "plone-portlets" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/16/c7/a57481b5daeca8fd1e93c573bfab2266f8c7a79962065081aee3bfb8fc8e/plone_app_customerize-2.0.2.tar.gz", hash = "sha256:23cc33c3beece92f67c5674d978300a49c341425f08f81cf27b70525d4cac67c", size = 28985 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/87/0e/0b0cd01f5051a9d7a9ffeaba8ea8b26cf828127a7e16256ea10669256a5b/plone.app.customerize-2.0.2-py3-none-any.whl", hash = "sha256:c4d31264a6f8d46a4b5cd3ead7d347362ec2bd7495a239e2398abb614e5f3bc0", size = 21713 },
+]
+
+[[package]]
+name = "plone-app-dexterity"
+version = "4.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "plone-app-textfield" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-contentrules" },
+ { name = "plone-dexterity" },
+ { name = "plone-formwidget-namedfile" },
+ { name = "plone-indexer" },
+ { name = "plone-locking" },
+ { name = "plone-namedfile" },
+ { name = "plone-portlets" },
+ { name = "plone-registry" },
+ { name = "plone-rfc822" },
+ { name = "plone-schema" },
+ { name = "plone-schemaeditor" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "plone-z3cform" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+ { name = "zope-browserpage" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-dottedname" },
+ { name = "zope-filerepresentation" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/bf/a2/10ca7300f8abd20e5e08a097a496ded899e06f5bd971bfbb6cafb9b7ee93/plone_app_dexterity-4.0.4.tar.gz", hash = "sha256:136f8622fd30b65cec5c7ecabdb58d37250099e39569d7bc77db332705a48d98", size = 228742 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/46/f4/c0110820db72cc4772fd8f09e87758df0df2a0bfc4bf5ee9a23791a7268a/plone_app_dexterity-4.0.4-py3-none-any.whl", hash = "sha256:0fecfd5d09c353d82e6843b2568e2bffb4d1cc8086c87f5dc60b482ccafe5190", size = 131043 },
+]
+
+[package.optional-dependencies]
+relations = [
+ { name = "plone-app-intid" },
+ { name = "plone-app-relationfield" },
+ { name = "z3c-relationfield" },
+]
+
+[[package]]
+name = "plone-app-discussion"
+version = "5.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-event" },
+ { name = "plone-app-layout" },
+ { name = "plone-app-registry" },
+ { name = "plone-app-uuid" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-indexer" },
+ { name = "plone-registry" },
+ { name = "plone-resource" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "plone-z3cform" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ff/b2/f93593376588aa19bc2d953ddba1c4c848e3cc223fe618e14e17c477082e/plone_app_discussion-5.0.0.tar.gz", hash = "sha256:3b00d9ad21555e5817806d9f460581755320677d4eacc8e5f5c595bd5dca2546", size = 147698 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/61/a1/8008de6276837041bf02c26e4e172206703943512a9b47b9ea3de868fc42/plone.app.discussion-5.0.0-py3-none-any.whl", hash = "sha256:bac8a6f5acb7eb9461489ae3d8629d1b24b393e6ca569d9822f5f4c763704164", size = 133212 },
+]
+
+[package.optional-dependencies]
+test = [
+ { name = "plone-app-contentrules" },
+ { name = "plone-app-contenttypes", extra = ["test"] },
+ { name = "plone-app-robotframework" },
+ { name = "plone-app-testing" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-contentrules" },
+ { name = "plone-dexterity" },
+ { name = "plone-protect" },
+ { name = "plone-stringinterp" },
+ { name = "plone-testing" },
+ { name = "products-mailhost" },
+ { name = "python-dateutil" },
+ { name = "robotsuite" },
+]
+
+[[package]]
+name = "plone-app-event"
+version = "5.2.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "icalendar" },
+ { name = "plone-app-contentlisting" },
+ { name = "plone-app-contenttypes" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-portlets" },
+ { name = "plone-app-querystring" },
+ { name = "plone-app-registry" },
+ { name = "plone-app-textfield" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-browserlayer" },
+ { name = "plone-dexterity" },
+ { name = "plone-event" },
+ { name = "plone-folder" },
+ { name = "plone-formwidget-recurrence", extra = ["z3cform"] },
+ { name = "plone-indexer" },
+ { name = "plone-memoize" },
+ { name = "plone-namedfile" },
+ { name = "plone-portlets" },
+ { name = "plone-resource" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "products-daterecurringindex" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "products-zcatalog" },
+ { name = "pytz" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f4/8c/88be0a53d3960454e6d9e5818a9b011807ae21ea1719f50e81fee8b7ee32/plone_app_event-5.2.1.tar.gz", hash = "sha256:d7c5ce7eabe05e7984ebee12020d2329c3f78b30289f9c9d31c99b8567a4c008", size = 176901 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/be/40/38f2e2c638300058208f7f73dacb3230f2ee93ce223acbe7349ffc9fcf79/plone.app.event-5.2.1-py3-none-any.whl", hash = "sha256:558ae35c85589223f9e89a0c74321ee732eb707a4cd2584bd277ce9d467d6a94", size = 151810 },
+]
+
+[[package]]
+name = "plone-app-i18n"
+version = "4.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-i18n" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope-viewlet" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ca/26/8dc0e7673e05359789518efc055c345bfd6ecad3d4caa223215b5ab6cc75/plone.app.i18n-4.0.1.tar.gz", hash = "sha256:56b24fd7cdd53353b3d355f3adc41c3d759fd91791d33ee0668c30968f8ba34f", size = 19879 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f5/da/759410c6378ee72edd485ddae3f927105913fcc272460c17228ce5b9d1ed/plone.app.i18n-4.0.1-py3-none-any.whl", hash = "sha256:fd83999a76d978f0e2c6dd3b75e27c08f671ae48620b27fe85426631961ad25d", size = 12353 },
+]
+
+[[package]]
+name = "plone-app-intid"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "five-intid" },
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope-intid" },
+ { name = "zope-lifecycleevent" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/34/3d/e2666ddb03d28a70792c64e0562d45baea8d3280fec3e0f54d4925b1a270/plone.app.intid-2.0.0.tar.gz", hash = "sha256:25b44d59e203403515d4ca060b92da1298c6999be3f9ef00b29fd912b4751bdb", size = 15407 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/86/83/0dc9b51d2c7e2e14bfc32bcee0d59958ff5657022495e78b4ba6e711d017/plone.app.intid-2.0.0-py3-none-any.whl", hash = "sha256:07ca280e16920aa7b83c2fefbbe909adff4bf3871fe792e99dbc46a01ea4e7c9", size = 16221 },
+]
+
+[[package]]
+name = "plone-app-iterate"
+version = "6.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "datetime" },
+ { name = "plone-app-layout" },
+ { name = "plone-app-relationfield" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-locking" },
+ { name = "plone-memoize" },
+ { name = "plone-registry" },
+ { name = "products-cmfeditions" },
+ { name = "products-cmfplacefulworkflow" },
+ { name = "products-dcworkflow" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-relationfield" },
+ { name = "zc-relation" },
+ { name = "zope" },
+ { name = "zope-intid" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/00/e4/3d37505920f7c50a8f59b1a785f316813e837191837c3ab29c0f1b7634be/plone_app_iterate-6.1.0.tar.gz", hash = "sha256:35a52d8e1fc9af7bc4d4a7d9e9e22aa84e1458fc50ce53c596a427bbc0c11498", size = 59754 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d9/86/b0d3eb0d88cf97d7aa02ba50051b0e9ad49d2242ef9865df95e0f279d555/plone.app.iterate-6.1.0-py3-none-any.whl", hash = "sha256:d000fa14f63fcd227ed508290f1fda549b84966b1deef375727cc02a20a81519", size = 67623 },
+]
+
+[[package]]
+name = "plone-app-layout"
+version = "5.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-content" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-relationfield" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-viewletmanager" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-formwidget-namedfile" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-portlets" },
+ { name = "plone-protect" },
+ { name = "products-cmfeditions" },
+ { name = "products-statusmessages" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/81/15/71a5b66218b4e1fdc01d6689a850f4906f54c7e5bd4b06f05f4f31743023/plone_app_layout-5.0.2.tar.gz", hash = "sha256:21129d21c042d950ae73f5cfcacfdb64f689136cfbb395b0e7901128ddff6a5c", size = 136343 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e0/f9/9325c6ef69fa6efc5d0e82b86d595ed1f7bde188543c74308cd6d876b665/plone_app_layout-5.0.2-py3-none-any.whl", hash = "sha256:684d0b3c6d7af888af001b2ae090d024a0ea5de797b66dec37905a03674d5509", size = 118906 },
+]
+
+[[package]]
+name = "plone-app-linkintegrity"
+version = "4.0.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-intid" },
+ { name = "plone-app-relationfield" },
+ { name = "plone-app-textfield" },
+ { name = "plone-app-uuid" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-registry" },
+ { name = "plone-uuid" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-relationfield" },
+ { name = "zc-relation" },
+ { name = "zope" },
+ { name = "zope-intid" },
+ { name = "zope-keyreference" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/58/1b/605e1b9dd129afaf4c3df782969b7a358bbdd20222e3eb4770d2a7e7f9ef/plone_app_linkintegrity-4.0.6.tar.gz", hash = "sha256:be0035838fc2963cf42a40fe6fc09c171ef249a7286f84f38fc0d91469bbf406", size = 45494 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/22/2e/15130bbe534a2ecdfa3282d83ac6d9901d88dbb8dfefd9779e00bd8701b7/plone.app.linkintegrity-4.0.6-py3-none-any.whl", hash = "sha256:d3fea0d05fe5bf5fb0d34428d1596d92884af87f2d2528d96520e592e73dd838", size = 38614 },
+]
+
+[[package]]
+name = "plone-app-locales"
+version = "6.0.30"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/6a/53/bface7c0c31039a269422cadb88e649ddc8ce668efac987210d84e02acf2/plone_app_locales-6.0.30.tar.gz", hash = "sha256:2af556335afeb5830b102785b41dfad668c5b59d64b6e5cf39d8708a1d0656f7", size = 11433155 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5e/c7/4e6231d5d7a68318902e33e07b5e557dcd72e016324ecab5e84bccde2741/plone_app_locales-6.0.30-py3-none-any.whl", hash = "sha256:c95f1aaeaffa0a628741303c1919558e7d93255ac3bf1d47a3a27f33ae33fca9", size = 11964440 },
+]
+
+[[package]]
+name = "plone-app-lockingbehavior"
+version = "2.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-behavior" },
+ { name = "plone-dexterity" },
+ { name = "plone-locking" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a6/40/c6c43a10be0c94ad48a4b627af9e943344293a1c68a340de3348dbd203f2/plone_app_lockingbehavior-2.0.2.tar.gz", hash = "sha256:e4bb1837026b09713628006247af8f4c39d6580f7dd0f261148d662653652f8b", size = 14849 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c4/c9/6d33edfc043aabcc85395ec36f17e2b97aeda12644cf7ee16addc6dcf248/plone.app.lockingbehavior-2.0.2-py3-none-any.whl", hash = "sha256:5a08a13ef67e29535c433a3a575deaf677fad77252b3c7b7e8ee0a4ee5eaa1f4", size = 7832 },
+]
+
+[[package]]
+name = "plone-app-multilingual"
+version = "8.2.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "plone-app-content" },
+ { name = "plone-app-contentmenu" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-event" },
+ { name = "plone-app-i18n" },
+ { name = "plone-app-layout" },
+ { name = "plone-app-querystring" },
+ { name = "plone-app-registry" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-dexterity" },
+ { name = "plone-i18n" },
+ { name = "plone-indexer" },
+ { name = "plone-locking" },
+ { name = "plone-memoize" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-schemaeditor" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "plone-z3cform" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfplone" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "z3c-relationfield" },
+ { name = "zc-relation" },
+ { name = "zope" },
+ { name = "zope-browsermenu" },
+ { name = "zope-intid" },
+ { name = "zope-pagetemplate" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/69/ea/38506781b519bb4bef1468b393a320a36b58a9f45aa16ae5e636b357dfd5/plone_app_multilingual-8.2.3.tar.gz", hash = "sha256:946e472b9f46547567183fa5ab71a308aea9d13849954b70df6e4c453d069205", size = 773637 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/45/da/dfb5c243fbfd3139c0538cb74cb7f78cb624af522b579540864e6ff2bb2d/plone_app_multilingual-8.2.3-py3-none-any.whl", hash = "sha256:cb248daa3d220d121251719eae64dec1661614c69ccba7dc376c6abcfc3eeeec", size = 239553 },
+]
+
+[[package]]
+name = "plone-app-portlets"
+version = "6.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "extensionclass" },
+ { name = "feedparser" },
+ { name = "five-customerize" },
+ { name = "plone-app-i18n" },
+ { name = "plone-app-layout" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-portlets" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "products-genericsetup" },
+ { name = "products-mimetypesregistry" },
+ { name = "products-pluggableauthservice" },
+ { name = "products-pythonscripts" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+ { name = "zope-annotation" },
+ { name = "zope-browser" },
+ { name = "zope-contentprovider" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ea/b1/6377f9cd1e6d53c3ffa3aab6e6d8fb54efd1441bba93494f724808f09710/plone_app_portlets-6.0.1.tar.gz", hash = "sha256:879cb6beb955d3aa4c9642330977df2c5f2da7ae80c643686eea333e803dcb47", size = 133602 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dc/1b/405d1c342bc070ad5e6503532bd4c0848dc72349a53638e38e022d207933/plone.app.portlets-6.0.1-py3-none-any.whl", hash = "sha256:69a6069a3606449a18b18911e5983d94303b7f3f4733808c656aa0c9be87b4e2", size = 144694 },
+]
+
+[[package]]
+name = "plone-app-querystring"
+version = "2.1.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-contentlisting" },
+ { name = "plone-app-registry" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-base" },
+ { name = "plone-batching" },
+ { name = "plone-i18n" },
+ { name = "plone-registry" },
+ { name = "plone-uuid" },
+ { name = "products-genericsetup" },
+ { name = "products-zcatalog" },
+ { name = "python-dateutil" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-dottedname" },
+ { name = "zope-globalrequest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/84e52f485faebfd6eec8546b71b32443de57e72ec935185170b7c041091b/plone_app_querystring-2.1.3.tar.gz", hash = "sha256:1a717fec974588c6a3ef51dc6d036c0e3f952fa4c23d3fec20abd392d57607b5", size = 49509 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/86/9d4940f2e9ee4eaf565a8d1c6b05f715d5bca9f91f3b6d69c78815899ff1/plone.app.querystring-2.1.3-py3-none-any.whl", hash = "sha256:5553d44af45b0e8c1c59600da38885ae99406612fc2a3093be6fd7d8c04ef529", size = 51058 },
+]
+
+[[package]]
+name = "plone-app-redirector"
+version = "3.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "plone-memoize" },
+ { name = "products-cmfcore" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b5/c9/d5f09929417cf0276cab517cdb2eef0d5af62bbd120cceba83202ad665c5/plone_app_redirector-3.0.4.tar.gz", hash = "sha256:781e123bc9fd9a8b4c3ea3f26e4b429bbe75918fbf355fe5dff7c66d1b5b2806", size = 30783 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ad/da/2584b7b61b599ee004a4a3784a31958baec9bf8eee3a5cba4b52f68bbd71/plone.app.redirector-3.0.4-py3-none-any.whl", hash = "sha256:17a9f88f8301b17b3b7924e6a23fe4f11822ba73ab38b045d0e7954e8562405d", size = 23683 },
+]
+
+[[package]]
+name = "plone-app-registry"
+version = "2.0.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-registry" },
+ { name = "plone-supermodel" },
+ { name = "plone-z3cform" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fc/e9/585768b090cd038c109c93dbd7f5ecb07462bcb70cc52e34ec5708e04a9b/plone_app_registry-2.0.6.tar.gz", hash = "sha256:63555b6affbe73140226c2f1c4984ecfb1b2c8d8d4967d9565ca1d50ce2f505b", size = 369380 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e4/3f/d6abe09f7d2d41c99c0d13ce7f6942a834e369422a36cf92f2e612d89027/plone.app.registry-2.0.6-py3-none-any.whl", hash = "sha256:64d9f6023bff4d2f3ed957409d05e005f42e8dc9201c811f58db6ed1e6722ba6", size = 45001 },
+]
+
+[[package]]
+name = "plone-app-relationfield"
+version = "4.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "five-intid" },
+ { name = "plone-app-intid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-dexterity" },
+ { name = "plone-rfc822" },
+ { name = "plone-schemaeditor" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "z3c-formwidget-query" },
+ { name = "z3c-objpath" },
+ { name = "z3c-relationfield" },
+ { name = "zc-relation" },
+ { name = "zope" },
+ { name = "zope-intid" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9f/ff/7a0b6840884c08d24b0070247e95dfdc7f7d294ef52d702eb46c3ce16b17/plone_app_relationfield-4.0.2.tar.gz", hash = "sha256:54f1efa958bf1c191ae9d2c074b63b996e429c7d1d52b7639e62d230cddbcf90", size = 27425 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0a/05/3958fe9f893b3aa2f84914be6f34930bd56f4d351d1edc78bb0886c2bfbd/plone_app_relationfield-4.0.2-py3-none-any.whl", hash = "sha256:6e7bd7ccbbbbf5180e3378f5aee61d7a0568098880be11b8731c11e20fd7a786", size = 28166 },
+]
+
+[[package]]
+name = "plone-app-robotframework"
+version = "2.1.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "babel" },
+ { name = "docutils" },
+ { name = "pillow" },
+ { name = "plone-app-testing" },
+ { name = "plone-app-textfield" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-i18n" },
+ { name = "plone-namedfile" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-testing" },
+ { name = "plone-uuid" },
+ { name = "products-cmfplone" },
+ { name = "products-plonepas" },
+ { name = "products-pluggableauthservice" },
+ { name = "robotframework" },
+ { name = "robotframework-browser" },
+ { name = "robotframework-selenium2library" },
+ { name = "robotframework-seleniumtestability" },
+ { name = "robotsuite" },
+ { name = "selenium" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "z3c-relationfield" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-i18n" },
+ { name = "zope-intid" },
+ { name = "zope-schema" },
+ { name = "zope-testrunner" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/2feb6728978068c82260890b5159f336728e7253f15296d54bbf5e7d185f/plone_app_robotframework-2.1.5.tar.gz", hash = "sha256:b8ad666dca1e97d4e93cd32e0913b3fd9e77d5d29ebe659b7df506179eef7c5b", size = 914229 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2a/70/365df62babfe66d447d750ecafbdef9af6d7c6ca0620abe538ba04f59d26/plone_app_robotframework-2.1.5-py3-none-any.whl", hash = "sha256:861daa35cf4de15c41f8cc17491e00b03478478ffdccf668ab6e3ca848afde71", size = 130926 },
+]
+
+[package.optional-dependencies]
+debug = [
+ { name = "robotframework-debuglibrary" },
+]
+
+[[package]]
+name = "plone-app-testing"
+version = "7.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "plone-app-contenttypes" },
+ { name = "plone-dexterity" },
+ { name = "plone-memoize" },
+ { name = "plone-registry" },
+ { name = "plone-testing", extra = ["security", "zca", "zodb"] },
+ { name = "products-cmfplone" },
+ { name = "products-genericsetup" },
+ { name = "products-mailhost" },
+ { name = "products-pluggableauthservice" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-dottedname" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/cd/d4/3a22c8fb0ba596104539ce6232e201bae9fc2de0a7850e902c9bfee39c4e/plone_app_testing-7.1.1.tar.gz", hash = "sha256:fb222daa55121475ddde36a8fdc5c417c3c10f8cc7397d621608fff2756bad83", size = 110969 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/05/af/b58f61ce97da562a576cc23ca7b548412069a9e033d8e7fa9832c8807133/plone.app.testing-7.1.1-py3-none-any.whl", hash = "sha256:2872475702935006dba93020789e9544255018334ef32ff172e7ccce7f2e862d", size = 49579 },
+]
+
+[package.optional-dependencies]
+robot = [
+ { name = "decorator" },
+ { name = "robotframework-selenium2library" },
+ { name = "robotsuite" },
+ { name = "selenium" },
+]
+
+[[package]]
+name = "plone-app-textfield"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/11/cb/d1f21dcc6d01b19ce30ad2288c27d8972c7d32e5d3e59ae6f851ddfef496/plone_app_textfield-3.0.0.tar.gz", hash = "sha256:be4df5fa6a24135ea2dfb80cfa6cdb27e8a8a96bffc73b50f402cef3219843ff", size = 36772 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f9/e5/d5c1bd46377b435549723c0225e899cc5aeea30b902e5a9726b6d5c6954a/plone.app.textfield-3.0.0-py3-none-any.whl", hash = "sha256:a277e19f81619abf02b376f71a9dfea860eac4e74656cdb9aedc38ebe19f09f6", size = 31705 },
+]
+
+[[package]]
+name = "plone-app-theming"
+version = "5.0.12"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "diazo" },
+ { name = "docutils" },
+ { name = "lxml" },
+ { name = "plone-app-registry" },
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-registry" },
+ { name = "plone-resource" },
+ { name = "plone-resourceeditor" },
+ { name = "plone-staticresources" },
+ { name = "plone-subrequest" },
+ { name = "plone-transformchain" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "python-dateutil" },
+ { name = "repoze-xmliter" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/91/e6/d7e2a08e290c350ef71c608fab568abf5b9510c8f036991ede9a8ec276dc/plone_app_theming-5.0.12.tar.gz", hash = "sha256:520e16b409db8bea49bd845c2861af5abec2c75067f27502b946667df6110249", size = 153182 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dd/32/8c9bd3fd3bbcdf23aec6a275aad151a763ae7af62965bcc5f3053be89f13/plone_app_theming-5.0.12-py3-none-any.whl", hash = "sha256:333a15b9314396c11de879484b05ab0d31c695ef46430df9f5dff24efde11eae", size = 125608 },
+]
+
+[[package]]
+name = "plone-app-upgrade"
+version = "3.2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "plone-app-theming" },
+ { name = "plone-base" },
+ { name = "plone-folder" },
+ { name = "plone-registry" },
+ { name = "plone-uuid" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfeditions" },
+ { name = "products-cmfplone" },
+ { name = "products-genericsetup" },
+ { name = "products-plonepas" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zodb" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b0/6a/77a6fa98e650b1bec26f866b8a3074e8cda35711862fc9fa492e0b854852/plone_app_upgrade-3.2.0.tar.gz", hash = "sha256:4b107389a8267d14e79ddf68eb79930eab63e46dd2e7738585d422c1d8a98235", size = 62891 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/90/52/03f27c60f1fa96884928bb647ad715a198a6cfe47f826619cb3ac458c81a/plone_app_upgrade-3.2.0-py3-none-any.whl", hash = "sha256:654db00881698d638ee211f30e7008dc233d4691e5673e7971dc0e019d4eafde", size = 73442 },
+]
+
+[[package]]
+name = "plone-app-users"
+version = "3.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "pillow" },
+ { name = "plone-app-event" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-formwidget-namedfile" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-namedfile" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-schema" },
+ { name = "plone-schemaeditor" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "plone-z3cform" },
+ { name = "products-genericsetup" },
+ { name = "products-plonepas" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+ { name = "zope-annotation" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/e3/3b/1df1503d704677f13b806b0d6cd949204e41685a1dc75d227c459ef36cb1/plone_app_users-3.1.1.tar.gz", hash = "sha256:8bf60f565da5a515453e50fe9bebd92f4b4ed24bd44db9957e67867535871a41", size = 87028 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6f/2b/7b7d0400d11145727fb1b8c3b2963cc6ffeb8b43b585dde1be749e3d9159/plone_app_users-3.1.1-py3-none-any.whl", hash = "sha256:5283e62dfdf00ff0957417005881acbfc8b91ce985eb46b766f9f5d8c68ab145", size = 87173 },
+]
+
+[[package]]
+name = "plone-app-uuid"
+version = "2.2.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-indexer" },
+ { name = "plone-uuid" },
+ { name = "products-cmfcore" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/3f/3b/82b98dbab18969005bdb5575dca11919951eefe84309567145fba3b8ccb8/plone.app.uuid-2.2.3.tar.gz", hash = "sha256:063008306fe4d94f68f29aa5cfab97f1d59dd30ff80b1571f53a5743cb1cfdfc", size = 19763 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ad/37/2a92787942b3d3ef59626d318beb95d961940c2c60758323c80bf955258a/plone.app.uuid-2.2.3-py3-none-any.whl", hash = "sha256:cc69b7a0ff8e0f5d02ab22c48b08b145716d92dbeb862f8c4d2cc6a5f3090ec7", size = 10067 },
+]
+
+[[package]]
+name = "plone-app-versioningbehavior"
+version = "2.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-dexterity", extra = ["relations"] },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-dexterity" },
+ { name = "plone-namedfile" },
+ { name = "plone-rfc822" },
+ { name = "plone-supermodel" },
+ { name = "products-cmfeditions" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "z3c-relationfield" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a8/8e/499d4bad43bf4a6163f7dce53a816189acaa451fd53218cfdcb8dc727c15/plone_app_versioningbehavior-2.0.4.tar.gz", hash = "sha256:be1af66d1a5f3792df7cad60f4e994f838401c2a40c9fd51b442c45d2d2e95f4", size = 30879 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/53/b9/59ae7df0c45756d6504875543410f2c41d8790751ff25bc405bdcb446c44/plone.app.versioningbehavior-2.0.4-py3-none-any.whl", hash = "sha256:661dfd0bca370b0ab7199ecbfbed84aac452d668b0a9d281de7e4ebe88e721d0", size = 31896 },
+]
+
+[[package]]
+name = "plone-app-viewletmanager"
+version = "4.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-contentprovider" },
+ { name = "zope-viewlet" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/44/01/2b0693c082785d6515bd0ebd1a6247070588af4cf6fd5678e78d5831945b/plone_app_viewletmanager-4.0.4.tar.gz", hash = "sha256:d1a8658f78f5efb3aeb702ed22dfe58037bc986fdcd8093f0347fa434a90ee64", size = 28218 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0a/77/a472ac897b120b79718c60ee8d9ff6a48456674aeca1af3b7c2b805daba8/plone.app.viewletmanager-4.0.4-py3-none-any.whl", hash = "sha256:dc91d9dad9b653e1e451c2424643bfcfbe8305ee2d8a3578eeba0d6f508b8b38", size = 21256 },
+]
+
+[[package]]
+name = "plone-app-vocabularies"
+version = "6.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "plone-base" },
+ { name = "plone-memoize" },
+ { name = "plone-namedfile" },
+ { name = "plone-registry" },
+ { name = "plone-uuid" },
+ { name = "products-zcatalog" },
+ { name = "pytz" },
+ { name = "setuptools" },
+ { name = "unidecode" },
+ { name = "z3c-formwidget-query" },
+ { name = "zope-browser" },
+ { name = "zope-globalrequest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/67/c8/2f4f64d3a93e98720a9a4fdc72b39d2a8ba8f8b1cff8fcafe7e19f2c03be/plone_app_vocabularies-6.0.2.tar.gz", hash = "sha256:ee9a0c462e0c5f4d4ed8ac9d5a006591352935a664f61273b2f6fdb60dafbf26", size = 60677 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a7/d3/c8be20467d7b26b4d58c81468f1b0e8a750fe1fbeefebc8408d69e603ea0/plone.app.vocabularies-6.0.2-py3-none-any.whl", hash = "sha256:7e2f923f00d1c832974978bed7a552611e1db1e0dedfce1a09652180747dc0ab", size = 56546 },
+]
+
+[[package]]
+name = "plone-app-workflow"
+version = "5.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "products-dcworkflow" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d5/17/a51374da9286e3ad3110feed2ebd3e56ffdb7f3a6854fc95cb9dc23618ba/plone_app_workflow-5.0.4.tar.gz", hash = "sha256:247e61db019489b3416d4e56725e71a5b18aea3c319437f4ea764d8afc598b54", size = 44208 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/fd/50a242144679363151cf84d78dd9d15dfb5eb37ed3e19cf54cd940e4777b/plone.app.workflow-5.0.4-py3-none-any.whl", hash = "sha256:7353b664bf69966d0ed98f1ce1186ec7c10f3718a41e55d753407b76b6f0a80d", size = 40545 },
+]
+
+[[package]]
+name = "plone-app-z3cform"
+version = "4.7.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-contentlisting" },
+ { name = "plone-app-textfield" },
+ { name = "plone-base" },
+ { name = "plone-formwidget-namedfile" },
+ { name = "plone-i18n" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-schema" },
+ { name = "plone-uuid" },
+ { name = "plone-z3cform" },
+ { name = "products-genericsetup" },
+ { name = "pytz" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "z3c-relationfield" },
+ { name = "zope" },
+ { name = "zope-deprecation" },
+ { name = "zope-globalrequest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ff/8f/753bd78b86d8d01ea7fbfba010ff131912712029892c951e53399750b0d1/plone_app_z3cform-4.7.4.tar.gz", hash = "sha256:adf986bd190b5b78ca8329e8bfecb3fd6061a4c21510da89e29174103089720e", size = 105964 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/32/45/dd385698c9769e712c1599db8789ee7031d428d39333fe9a3ed081bd5ab3/plone.app.z3cform-4.7.4-py3-none-any.whl", hash = "sha256:9778243611e0b1d68bdc3ebad394f0082665509051af34fd28fa84a2a46db36c", size = 95060 },
+]
+
+[[package]]
+name = "plone-autoform"
+version = "2.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "plone-supermodel" },
+ { name = "plone-z3cform" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b0/1d/3f87c966c42e44e6e2208d1d7ef0666c94ff4e4662d115cec66a3408712b/plone_autoform-2.0.3.tar.gz", hash = "sha256:91d3d58af51d109373cba7691d6e1ff99c5e3fbfdad256f24c8da70bd2a00460", size = 51486 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bf/bd/e0d4513b9c177b309dd2d8b4fc9f71bb2761684891bf223cdc96d5b7ce25/plone.autoform-2.0.3-py3-none-any.whl", hash = "sha256:bd7f3b5392739660cb7c0177eacff94e73f203eaa6aa18cb83b6f9e361005699", size = 45146 },
+]
+
+[[package]]
+name = "plone-autoinclude"
+version = "2.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-configuration" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/bc/76/6a202c45fd0fbccec9e641eaeca1f424ab8e84077374aab557c6497d1d4f/plone_autoinclude-2.0.3.tar.gz", hash = "sha256:f481adad3cbae3130026bacd60127f48a161ec35a33cd1c218a5c63ce419241c", size = 41196 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/41/75/bdc1ec30760ef14578cde9039a9bc4a9543f31dcbe707984a51533fa0118/plone.autoinclude-2.0.3-py3-none-any.whl", hash = "sha256:28961b8631187fb491cf1e78033bceb03529ddf75482ee6f954d01cdc4fe1e3b", size = 21327 },
+]
+
+[[package]]
+name = "plone-base"
+version = "2.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-batching" },
+ { name = "plone-registry" },
+ { name = "plone-schema" },
+ { name = "plone-z3cform" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfdynamicviewfti" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b4/67/d371de812782ec1dcac7e1f7d45a877c7fbf374152a6035dfb1699ab8e3d/plone_base-2.0.3.tar.gz", hash = "sha256:0906ee5229b4dcd7f806373265568e2c1f47dcd91948cdad6cb1b93bd26303a8", size = 52489 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f2/d2/a373d5046f8e6c97813a5d04f20f31b0adb5c96095c8b69782bdaed8d988/plone_base-2.0.3-py3-none-any.whl", hash = "sha256:66edecb9fbd8a0b853c9a637aeef13ad1c08d033cd49858b8f78df0a6c11de91", size = 57192 },
+]
+
+[[package]]
+name = "plone-batching"
+version = "2.0.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/68/77/10cab32f8cc9dcc0b73c1679ed1504e59085d0ec045a4aa26f41b8a92766/plone.batching-2.0.6.tar.gz", hash = "sha256:7612808038a54a7ee173b041c507b07f7b2e0a75117918340330da26a1cce21e", size = 22026 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0d/8d/e02348cabb39a9e546016666cb42c16e4b34b379e3366475bc7444f3c4ad/plone.batching-2.0.6-py3-none-any.whl", hash = "sha256:985fcc86bd58232b391fee648a7f0518662b7f0fbbff88a38ec57e45091b6fdd", size = 18582 },
+]
+
+[[package]]
+name = "plone-behavior"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-annotation" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/8c/12/6405b8e23561a23eaec78a62fedc13ae276b3eae90fe1ca1bd62f9615230/plone.behavior-2.0.1.tar.gz", hash = "sha256:abad04798d1f6f1a5e67e5b51f4169640db50210fa81223e87a45c7d47544aba", size = 27814 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/70/a2/c1bc62639a25f0e96f8787cb5f05040d606a9c4a43f9f09e9c3877dbb502/plone.behavior-2.0.1-py3-none-any.whl", hash = "sha256:2befc5c45a0a645bbc07dd56ac248a2b384fb0dee0390e010b3158fcfebb20f7", size = 24049 },
+]
+
+[[package]]
+name = "plone-browserlayer"
+version = "3.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/41/34/88e5abd6f2ec01b8428e4e851180add22467498325b7f47b82d849b1f85f/plone.browserlayer-3.0.2.tar.gz", hash = "sha256:3862c370939d0b978c756d8a2ef32570acbbe86254011332cabc8b6aa6cb6c1d", size = 17755 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1d/fc/20955d87e6aaed6a3839bdc69101823d36460bb74a7195e080fcd95e1f07/plone.browserlayer-3.0.2-py3-none-any.whl", hash = "sha256:3576962f1a4f35777438e9c3ef6b584890728a1a3a1684041ff3c1fbf6699a26", size = 12924 },
+]
+
+[[package]]
+name = "plone-cachepurging"
+version = "3.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-registry" },
+ { name = "requests" },
+ { name = "setuptools" },
+ { name = "z3c-caching" },
+ { name = "zope" },
+ { name = "zope-annotation" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-globalrequest" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b5/be/7fe78f064e76b8eb6efe234d3debcd80ef0bcf67f53e14fcf747a3bd66e6/plone.cachepurging-3.0.2.tar.gz", hash = "sha256:9f770e2861a57f9a70af1699bef6a970d15e99ba5293034b93bb0bdb5f783782", size = 38892 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/24/94/a454d4eb50a8dfc99a6026204c47e65624222808c9597b361f355816a114/plone.cachepurging-3.0.2-py3-none-any.whl", hash = "sha256:ae27366d1170fa71d676fecfa790c99bed34f308cb2b047b356bea2a70387e42", size = 28087 },
+]
+
+[[package]]
+name = "plone-caching"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-registry" },
+ { name = "plone-transformchain" },
+ { name = "setuptools" },
+ { name = "z3c-caching", extra = ["zcml"] },
+ { name = "zope-component" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/6b/33/430b128b194310baafabf31e4730e9e16b87b468fc34c13e1222216f4fbd/plone.caching-2.0.1.tar.gz", hash = "sha256:f4bdd1b2816f3e2257e9727a6287965898cd2f3b3cde1ee12d4fc75a93512e6f", size = 30477 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bf/50/357769a5d3347a49500a62b0d3fd82a75acb79d80644af72f5f00d52ed61/plone.caching-2.0.1-py3-none-any.whl", hash = "sha256:caba0f9aa46d11f475e4d65199681e9e47e56381f25058b0c925e59ea7f17182", size = 21684 },
+]
+
+[[package]]
+name = "plone-contentrules"
+version = "3.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-componentvocabulary" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c4/4a/f7d557a8b42d1003d44e0044ed8209120278305ebd66e4c838cb46c62c2e/plone.contentrules-3.0.1.tar.gz", hash = "sha256:4fb0d30d534c63044015b661701710d2ce8cfcf0ca38cb833403da8945278eb5", size = 26107 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f6/0a/69f27be316be427c80f91e0a54d3141327046c5ae300cc8134556462f925/plone.contentrules-3.0.1-py3-none-any.whl", hash = "sha256:a1e285ca033c90c5c2074a1cbf629ea84ca8ba472ce8747a482a472b8545eb72", size = 23322 },
+]
+
+[[package]]
+name = "plone-dexterity"
+version = "3.0.7"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-alterego" },
+ { name = "plone-app-uuid" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-behavior" },
+ { name = "plone-folder" },
+ { name = "plone-memoize" },
+ { name = "plone-rfc822" },
+ { name = "plone-supermodel" },
+ { name = "plone-uuid" },
+ { name = "products-cmfcore" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/96/14/fe220d8eb5fd6e8608eb6e7f8c4bf738ffb6c25a5c86a6d5c416938a1ad5/plone_dexterity-3.0.7.tar.gz", hash = "sha256:a911069f89553f003946e47331951a1d79afe0982ef9105121856d11a2386617", size = 122101 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/97/1b/cd1fddda954b8c9344a9e7f6fdfa7b899af781f43b46129579aa4626f215/plone.dexterity-3.0.7-py3-none-any.whl", hash = "sha256:b4571dd29fe69461da56caa9bd68664a9a5518e6e76da0b2a3f5327149904a93", size = 98456 },
+]
+
+[[package]]
+name = "plone-distribution"
+version = "3.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "jsonschema" },
+ { name = "plone-api" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-exportimport" },
+ { name = "plone-i18n" },
+ { name = "plone-protect" },
+ { name = "plone-rest" },
+ { name = "plone-restapi" },
+ { name = "products-cmfplone" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "z3c-unconfigure" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b7/2a/2286ebbb34b3384984b04b3b1aaa0829d9ca80bc8c04314b04f811f130e7/plone_distribution-3.1.1.tar.gz", hash = "sha256:393659d0381fb913b54095e46370a2a1f76a33f796e30d4d4a7f93875bd6b6be", size = 629402 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b1/cb/27e4c0739c51d87e8afb245626f0dd7f3b752c90551b5abd74ca46501d3e/plone_distribution-3.1.1-py3-none-any.whl", hash = "sha256:b44f389386ffa5620bdcb82abeb753496a2ef2ff221c19e108914d2aa312c68e", size = 603803 },
+]
+
+[[package]]
+name = "plone-event"
+version = "2.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "python-dateutil" },
+ { name = "pytz" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/92/b2/f52e8b582c82322724931a8c4dea4d81c03b65fc30533206c4a85646d6de/plone_event-2.0.2.tar.gz", hash = "sha256:ca38899454d0fd1da872793826f87dc8cd3747dd11d909a6e5b705b020912e78", size = 33849 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/af/1803bcc73c12997f10fbb7ee3163f9bd7451c9e98a086f86932585a58a57/plone.event-2.0.2-py3-none-any.whl", hash = "sha256:417284358125fb9d4fd4daab93495d311a07f6a559a2e3bc62488b5e8ee5c613", size = 26316 },
+]
+
+[[package]]
+name = "plone-exportimport"
+version = "1.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-api" },
+ { name = "plone-app-contenttypes" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-redirector" },
+ { name = "plone-app-textfield" },
+ { name = "plone-app-users" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-namedfile" },
+ { name = "plone-restapi" },
+ { name = "plone-uuid" },
+ { name = "products-cmfeditions" },
+ { name = "products-cmfplone" },
+ { name = "products-dcworkflow" },
+ { name = "products-plonepas" },
+ { name = "products-portaltransforms" },
+ { name = "python-dateutil" },
+ { name = "setuptools" },
+ { name = "z3c-relationfield" },
+ { name = "zc-relation" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/10/b0/9605d69ff27a9ebbd87efcc53d5efab9f9c06ebce9263e4d371934359e81/plone_exportimport-1.1.0.tar.gz", hash = "sha256:a85420732f319abfc3d40f4dee214065e4de15a77cf3e5f82dbbdf2df410d5aa", size = 194933 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0f/ed/89e1dcf88e4f7809161578ba78d16845dbed7ad72ef8dcfd23175ecb9f20/plone.exportimport-1.1.0-py3-none-any.whl", hash = "sha256:004b68df86aceb10a00de90d4f3dfc085960b199b8e225a2fad80e5474f0bd45", size = 64623 },
+]
+
+[[package]]
+name = "plone-folder"
+version = "4.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0f/a0/9f3a4eaa1e844c419092e599d2b308af965b58bef061e9203b0dc161c631/plone.folder-4.0.1.tar.gz", hash = "sha256:0082abaa129fa434f4f5841164108e3db76e19e1ede8893e2bc3b14dc4883478", size = 30876 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ce/0b/83624d18a1c370a50a84890046d012d6393b851fb1648fa315d3ae5dadae/plone.folder-4.0.1-py3-none-any.whl", hash = "sha256:68886e45058190a2a005ef9247b199ee0c7f51bdefcde5c6419de8c0fe25ac5e", size = 25967 },
+]
+
+[[package]]
+name = "plone-formwidget-namedfile"
+version = "3.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "plone-base" },
+ { name = "plone-namedfile" },
+ { name = "plone-registry" },
+ { name = "products-mimetypesregistry" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope-annotation" },
+ { name = "zope-size" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ce/3d/355ad0d9e1261831ebc98798b402566d9781a57067e1dbbaaa768733c216/plone_formwidget_namedfile-3.1.1.tar.gz", hash = "sha256:eae172cea7aaa61597a80fcd41af6406a1ab4386296d3a7530db0bd7b407fd74", size = 43470 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7c/61/3bb704a353b5ee55595a4c5535a2cadb7644bb27a67c9707c31b1d4d4a12/plone.formwidget.namedfile-3.1.1-py3-none-any.whl", hash = "sha256:51f4db07b57382ce05c2746ad0911d82c880ac6cac0b9a2825241963b47daf3d", size = 34254 },
+]
+
+[[package]]
+name = "plone-formwidget-recurrence"
+version = "3.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "products-genericsetup" },
+ { name = "python-dateutil" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ce/32/8f7416541c8bf2876024aeac2385e08a70d4112f5c9972d9cc0c5e90e001/plone_formwidget_recurrence-3.0.5.tar.gz", hash = "sha256:a46dc61538c53b797ad55eb92c21b516c3020b69664cdd11794f5819304a9d45", size = 26939 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f8/9b/6b49a1183e7aa40996bf87716f62b02ab83d559524cc9da90428523d10bc/plone.formwidget.recurrence-3.0.5-py3-none-any.whl", hash = "sha256:3587e0eeea21299c9647cd10d05b53cafc4556570189c637ced4574189509b11", size = 18086 },
+]
+
+[package.optional-dependencies]
+z3cform = [
+ { name = "z3c-form" },
+]
+
+[[package]]
+name = "plone-i18n"
+version = "5.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-autoform" },
+ { name = "plone-registry" },
+ { name = "plone-subrequest" },
+ { name = "plone-supermodel" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "unidecode" },
+ { name = "zope" },
+ { name = "zope-globalrequest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f1/0c/965dd58ed801ab7e7636b9e8fbdf8eab9350250f229560ef9933525876bc/plone_i18n-5.1.0.tar.gz", hash = "sha256:99a29adec3a72d4e4ecd1b497ac5707e4169427649a47cb14fa36df76095d561", size = 136884 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fe/95/2af8e252206b0505e95a2cb8a7ce5fe7e6c7b6e20f5b248e72d4f52ae126/plone_i18n-5.1.0-py3-none-any.whl", hash = "sha256:ab9e6f3f36cbe711913d0cc3db3546d9a6d3d66cd83cc777cb44ebd79e5b2e0f", size = 199026 },
+]
+
+[[package]]
+name = "plone-indexer"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b0/99/513f61019848b637d15a5b782e2d2a65e490efee3992a5dcfcbde837a3d2/plone.indexer-2.0.1.tar.gz", hash = "sha256:4c962c500f214cbcad6fa5a50604d5c70adbf11c981fae0fa8a2ea8a7f788701", size = 17021 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d2/b3/2f29c8cd7ea90dd751ac8bbe59734135f73955eb8f48fdcec49c6a9b3801/plone.indexer-2.0.1-py3-none-any.whl", hash = "sha256:85e8c6f38fb06e48b46849d6ae1b85e9bda3ec6bb3572a70e473ab0e7ceb2d4e", size = 15197 },
+]
+
+[[package]]
+name = "plone-intelligenttext"
+version = "4.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ee/da/b006afc3ad1b732195fc98fc18902d4716dd193dfb8c7f2d7670e6402dd4/plone.intelligenttext-4.0.1.tar.gz", hash = "sha256:54eea9214cfc8c68766d2f567df3a65547555690010ea56f0cac441388c62dc7", size = 18760 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b3/d0/49c18bfb931b935d425087113e43b08129edc5b7a35bbabe6a21276adb7f/plone.intelligenttext-4.0.1-py3-none-any.whl", hash = "sha256:bbfbd4fa76ead210527524b61f3c7e51d39076788fd17cb3dda5c2f2c1be720d", size = 10278 },
+]
+
+[[package]]
+name = "plone-keyring"
+version = "4.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "zope-container" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/87/b4/f1b0627437065903791c7259fa7cb9d3693cbc966f915551090954da3bb6/plone_keyring-4.0.2.tar.gz", hash = "sha256:37320393120a11eaec91296117f1c672b4da03cbb4febc06844a63e4215a9c53", size = 12077 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ba/18/d12dca693917930276e81af0c0de34ad842670403179fd636bb40a8b8dc9/plone.keyring-4.0.2-py3-none-any.whl", hash = "sha256:fbb6db175df724f48d2bf2c81f7bc06825b8a1e6601c876cc57db70eaf397d1f", size = 10743 },
+]
+
+[[package]]
+name = "plone-locking"
+version = "3.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/30/8f/045bc0cdab8e3e4e5e8ccf1609ef1ef87ded37724f18abc47cbc59b88701/plone_locking-3.0.2.tar.gz", hash = "sha256:480531e9f55bea48dded76718cd2d1afbc097042e2cbc2b36624362c9d0b3ee6", size = 23423 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2e/ce/900608c0d9bc3c5a8a09417c053157dc4ca27977a020faceeb15e29bdd75/plone.locking-3.0.2-py3-none-any.whl", hash = "sha256:19f78f9108a666d0d0d9077259e74713ce23d98a3b713db273613fcdc5f03e1a", size = 16872 },
+]
+
+[[package]]
+name = "plone-memoize"
+version = "3.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-annotation" },
+ { name = "zope-component" },
+ { name = "zope-globalrequest" },
+ { name = "zope-interface" },
+ { name = "zope-ramcache" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d9/53/0c2bdefa958431e5c2f95f32304451396fb1bd741ce5e4bd5cd4730368cb/plone_memoize-3.0.3.tar.gz", hash = "sha256:587af3cbc179d3bac066aacbd6c151d79de6b7c75445cab206013996c8f89677", size = 26362 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6c/f8/f0685b5abdc1b6b276e37cd1ba4375390862423d7dd0d22d3a0ffa12f954/plone.memoize-3.0.3-py3-none-any.whl", hash = "sha256:cdef5d914f9d0b2bb3a7a94750ec5dc74d75606f0c7b05b44525d34bd48807c6", size = 25585 },
+]
+
+[[package]]
+name = "plone-namedfile"
+version = "7.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "beautifulsoup4" },
+ { name = "persistent" },
+ { name = "piexif" },
+ { name = "pillow" },
+ { name = "plone-app-uuid" },
+ { name = "plone-base" },
+ { name = "plone-dexterity" },
+ { name = "plone-memoize" },
+ { name = "plone-protect" },
+ { name = "plone-rfc822" },
+ { name = "plone-scale", extra = ["storage"] },
+ { name = "plone-schemaeditor" },
+ { name = "plone-supermodel" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "z3c-caching" },
+ { name = "zope" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-copy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5c/01/37397fce3090f0521980593f1ed04fb6b5220297fc798d696bcee51e0379/plone_namedfile-7.0.1.tar.gz", hash = "sha256:93ba3cab927168afea18d33d92f861b95a67fba9a7f3d5fd1ef8f81e32ebd3ea", size = 331338 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/19/7f/8686d80284ada45af236d6d64a48a450b3d216fb7911c6b3e16550f9629a/plone.namedfile-7.0.1-py3-none-any.whl", hash = "sha256:7042a87b46a8691a277dca4b630c18ecddf5857e0f0dad41941ce201a5efedf2", size = 326412 },
+]
+
+[[package]]
+name = "plone-outputfilters"
+version = "5.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "beautifulsoup4" },
+ { name = "documenttemplate" },
+ { name = "plone-app-uuid" },
+ { name = "plone-base" },
+ { name = "plone-namedfile" },
+ { name = "plone-registry" },
+ { name = "plone-uuid" },
+ { name = "products-genericsetup" },
+ { name = "products-mimetypesregistry" },
+ { name = "products-portaltransforms" },
+ { name = "setuptools" },
+ { name = "zope-cachedescriptors" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/40/94/5b480acee631b9062ccb6051a7dd79bdce11437161aa52a973625cbbe09e/plone.outputfilters-5.0.4.tar.gz", hash = "sha256:36309b1d511213888afcb271bed3e06d2e72ce263a76d4d1284b68d70cd6b8cb", size = 60004 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/17/5c/be51bca374874ab18be4bab58ffdb63cd699be4aaf2cbe77abf81b0c7671/plone.outputfilters-5.0.4-py3-none-any.whl", hash = "sha256:ea7ad027128ee45ccf2a086f6cf9d9da93ed1c3f44813127b5bb5a997984029d", size = 54038 },
+]
+
+[[package]]
+name = "plone-portlet-collection"
+version = "4.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-portlets" },
+ { name = "plone-app-querystring" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-portlets" },
+ { name = "plone-registry" },
+ { name = "products-genericsetup" },
+ { name = "products-mimetypesregistry" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ed/d8/aebfdf856098da3d6029c23cd31087a008f7869225b7ff854c6999f00769/plone_portlet_collection-4.0.4.tar.gz", hash = "sha256:d105ed621e4c7c7366b14506eb896919ae3ca663e0d5f7af9ab07b81046ff415", size = 27768 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/83/90/b436bf4b0d5a4d9cc410d3f3f4ad0390d8a101f43c58fe46a953baf89d67/plone.portlet.collection-4.0.4-py3-none-any.whl", hash = "sha256:c800b0134005972949c8abc124a69841268882080c2fe4988afe5cd5548971fb", size = 18780 },
+]
+
+[[package]]
+name = "plone-portlet-static"
+version = "4.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-portlets" },
+ { name = "plone-app-textfield" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoform" },
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-portlets" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5c/9f/4818a2661adea60bd01ffdf4157c16651b475bfd5ed983ece6e329847859/plone_portlet_static-4.0.4.tar.gz", hash = "sha256:a78993570a1410138f0d56ac0a07061f9584cdcc5de1cd174da226abc4cb6224", size = 21322 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a9/3e/f8168842f6f8b650c6fdd499bb824b1b0cefd8e4c8bb29ac649a4e0579c0/plone.portlet.static-4.0.4-py3-none-any.whl", hash = "sha256:29f4aef5d479778c009bb11b9425fbc9e251f361f57fc030cb9aa462249500c9", size = 12517 },
+]
+
+[[package]]
+name = "plone-portlets"
+version = "3.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "plone-memoize" },
+ { name = "setuptools" },
+ { name = "zodb" },
+ { name = "zope-annotation" },
+ { name = "zope-component" },
+ { name = "zope-container" },
+ { name = "zope-contentprovider" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-site" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/95/ca/143904e3fd72de2562fea3bb96fa671710a0b4d5705bbebe1132bc96d281/plone_portlets-3.0.2.tar.gz", hash = "sha256:8bf966aeeb01d1fab9681ab722eaffa785072a2f1d0ea7ee5d504b2ac91b08b2", size = 36916 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3b/0e/7a80bd4628f7cdf87e0765cb45efc242d5818849e009db266feb75407383/plone.portlets-3.0.2-py3-none-any.whl", hash = "sha256:39f7fed7a664de5c5a7fc954a1f6de2eabd40e56e63438983e519021cebe9fa0", size = 32155 },
+]
+
+[[package]]
+name = "plone-protect"
+version = "5.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "collective-monkeypatcher" },
+ { name = "lxml", extra = ["cssselect"] },
+ { name = "plone-keyring" },
+ { name = "plone-scale" },
+ { name = "plone-transformchain" },
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "products-pluggableauthservice" },
+ { name = "repoze-xmliter" },
+ { name = "setuptools" },
+ { name = "z3c-zcmlhook" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b2/05/00f04bedf6cb1571f47857069181c277a0d8f83d9e3c99a4349efd117dc1/plone_protect-5.0.3.tar.gz", hash = "sha256:812f1735dd53981144819b390c6baf18311b228e6f7ed990b8fa8cbd7245cd91", size = 35218 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0c/22/7e98ccea1e0ab7ff3194bc1d9681622ebabbb2e18a78d4203b5beb8088f5/plone.protect-5.0.3-py3-none-any.whl", hash = "sha256:08bc0e49762184da022f7210e0c8350143a2ba7af45cc46811de4fab03b6794a", size = 31772 },
+]
+
+[[package]]
+name = "plone-registry"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/33/f5/011bf18de3ab917eb1dd67b9c44b220a37d19a92f56d9da26d260a291f37/plone.registry-2.0.1.tar.gz", hash = "sha256:4a19201727e3665f98ca742c408f9dab27b36a2fc48f4e9a0ea3864df9eebb8c", size = 48775 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/43/6a/8cae3a4bd75ad7b8e3f8dfee31600b44b3c162d72efd7dcab436fdf1df61/plone.registry-2.0.1-py3-none-any.whl", hash = "sha256:34108d1ead452002a5d5d8ddf8813dfe111da53b8cedeb56332e555afd73e888", size = 37634 },
+]
+
+[[package]]
+name = "plone-resource"
+version = "3.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-caching" },
+ { name = "products-btreefolder2" },
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "python-dateutil" },
+ { name = "setuptools" },
+ { name = "z3c-caching" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/73/8b/92c405df4f9144e2569d9f61e910f9a83d23d185aeb76ca9ee2de79df607/plone_resource-3.0.2.tar.gz", hash = "sha256:f3fd5e17d1f9a0aad64e24daf25b5047fba8066844d9ee49c63139c63ba52823", size = 36804 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1d/27/ee74828054e062b2b4be8b137f63035d4f79ec1e5029cd82a465a228e1c7/plone.resource-3.0.2-py3-none-any.whl", hash = "sha256:e4934079854849b438ebfd740b717f9e8362ff8dc934026abad733ccb420b904", size = 35889 },
+]
+
+[[package]]
+name = "plone-resourceeditor"
+version = "4.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "plone-resource" },
+ { name = "plone-staticresources" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ce/92/ff5121e8bfa3a91a7e8ef39a8529f42560c8f02023bcade256cdf1bb5691/plone.resourceeditor-4.0.1.tar.gz", hash = "sha256:1801057af91c6ad608ee537e510ecce74553327a54bd68086ae1dee0f3f9097a", size = 24753 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7b/7e/425d19ce843d78c5608ed7690223a3093b214c75f5849ba0a74d50ca3882/plone.resourceeditor-4.0.1-py3-none-any.whl", hash = "sha256:104a8b55a7f5290d8e8ba49e28d97c46077d11f0c00d374e598fef2cd09bdb96", size = 16859 },
+]
+
+[[package]]
+name = "plone-rest"
+version = "5.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "collective-monkeypatcher" },
+ { name = "plone-memoize" },
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-browserpage" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/da/51/910242034d1ce71a811faf8d9013825e4d5e47daea54a0a7d494de80a1de/plone_rest-5.0.0.tar.gz", hash = "sha256:95d6650544120c1d0f3ba0cbda20587111c6357b301229c7c1303b9919877ba4", size = 109364 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/94/8b/6454a16de51f6b3b6a3fd2dcc5de775e18ab955d5ae820efba88a101b727/plone.rest-5.0.0-py3-none-any.whl", hash = "sha256:59b59d0b4d3d77bb61ea0b7ce5945c9cf53a8d8a95439d24313b99384c5e726d", size = 108760 },
+]
+
+[[package]]
+name = "plone-restapi"
+version = "9.13.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "packaging" },
+ { name = "plone-rest" },
+ { name = "plone-schema" },
+ { name = "products-cmfplone" },
+ { name = "pyjwt" },
+ { name = "python-dateutil" },
+ { name = "pytz" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/17/17/da4ae2cc0319e7d6938e5264fe91affed6ff629d8b7ab571a0aae018eda5/plone_restapi-9.13.3.tar.gz", hash = "sha256:dc00af068953ac6da74433ce0e49e10587fcdcdcf806025ad215692e1e04392d", size = 2968347 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bf/94/e97689d2079356cedbbac57bdb919cad14aa5081841d4fe3d18ca45c3fe3/plone.restapi-9.13.3-py3-none-any.whl", hash = "sha256:62de7e6950bbfda24655043fad7eeeea1ac72ededc3c0a6118f4eeeee39cba1f", size = 3090565 },
+]
+
+[package.optional-dependencies]
+test = [
+ { name = "collective-mockmailhost" },
+ { name = "plone-api" },
+ { name = "plone-app-caching" },
+ { name = "plone-app-contenttypes", extra = ["test"] },
+ { name = "plone-app-discussion", extra = ["test"] },
+ { name = "plone-app-iterate" },
+ { name = "plone-app-multilingual" },
+ { name = "plone-app-testing" },
+ { name = "plone-app-upgrade" },
+ { name = "plone-rest" },
+ { name = "requests" },
+]
+
+[[package]]
+name = "plone-rfc822"
+version = "3.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "python-dateutil" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/67/9c/3348a3676e54c6a814ab40c990ddbdbcffc5cb74330e38eab6250b42de4a/plone.rfc822-3.0.1.tar.gz", hash = "sha256:2a4a58693203351f764293142bdecc6ccd203ad9a660b90fb7f001185a0185ac", size = 38437 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bb/c2/f1ef403b42c16f4a3c108644e61864dc389ab0b054d085d85336ae82719d/plone.rfc822-3.0.1-py3-none-any.whl", hash = "sha256:a1d832646e7a20c968205550765dbe86c45b6e04c7885fe8e48819ae52b547af", size = 29196 },
+]
+
+[[package]]
+name = "plone-scale"
+version = "4.1.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pillow" },
+ { name = "setuptools" },
+ { name = "zope-annotation" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/86/0c/ed5644fbd1965cd050beb7d6abdfa795953bfd78876a5b6558dce333951d/plone_scale-4.1.4.tar.gz", hash = "sha256:1744bf91671e4e1448f98d79781be6999fd994192d59c883cac597034e66b66c", size = 2191615 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/42/56/61e7a488a79029d73c23af592e670bf0ed31af5d4829bfaebaf918a8dcb6/plone_scale-4.1.4-py3-none-any.whl", hash = "sha256:963d5f9616da2620d1ea90923fd25de56603484f909e2dd09b6952b34a9d5152", size = 2186536 },
+]
+
+[package.optional-dependencies]
+storage = [
+ { name = "persistent" },
+ { name = "zodb" },
+]
+
+[[package]]
+name = "plone-schema"
+version = "2.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "jsonschema" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope-i18nmessageid" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b9/bf/0de04f77979ee23b92aff49fe263480f23a8a2a93ed4c2a4a941efb3115f/plone_schema-2.0.2.tar.gz", hash = "sha256:1422ebcfb338203a67bc054b00c32ee96536c7cb42e0962d9a7c3d7b25c6b2ef", size = 11757 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/64/66/0d72890697fac1f1a5743699a9b12c08ce9862ba9fd10d38f0182858e257/plone.schema-2.0.2-py3-none-any.whl", hash = "sha256:7c408fa366a2d9de2022c460966f3da4ffe6a5ef95fff41f6323245f8814a776", size = 12832 },
+]
+
+[[package]]
+name = "plone-schemaeditor"
+version = "4.0.11"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "plone-autoform" },
+ { name = "plone-memoize" },
+ { name = "plone-protect" },
+ { name = "plone-supermodel" },
+ { name = "plone-z3cform" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-component" },
+ { name = "zope-container" },
+ { name = "zope-event" },
+ { name = "zope-globalrequest" },
+ { name = "zope-i18n" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0e/64/2c5ed39699f0531ef3498180b5c7f63052fea9c3790e401347fb323e3ebe/plone_schemaeditor-4.0.11.tar.gz", hash = "sha256:c6c9001ef2aa2492af9a9fc78053411feebefccc14ef4f1ab5c226307b9b699a", size = 48113 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/11/ca/b50458efaefb18d680ad43d9e0c7b81b13321a91f4d523fc98a022857f14/plone.schemaeditor-4.0.11-py3-none-any.whl", hash = "sha256:4456523d498de2c7961b737870c18bbd2b1605dad6e332458f332cfae134bb84", size = 50986 },
+]
+
+[[package]]
+name = "plone-session"
+version = "4.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-keyring" },
+ { name = "plone-protect" },
+ { name = "products-genericsetup" },
+ { name = "products-pluggableauthservice" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f8/2c/647ded47fac3e4cb714c34eef884cb46ea1ff1ae9f69a3d21e691c67c188/plone.session-4.0.4.tar.gz", hash = "sha256:35bd27a23601bcdb9dd4ab4bc43e83d3cb5cd495ea432bd1a3bc6ce94afe0fe5", size = 35792 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/03/32/a08f4a117bae8ac650504b62799ce75441acb1f1f97da7eb7ba9b2a3bfff/plone.session-4.0.4-py3-none-any.whl", hash = "sha256:0949b2ad92f057e9558fb1a638940279dfac8a7fbcba74c22fb61acfcec1a328", size = 28651 },
+]
+
+[[package]]
+name = "plone-staticresources"
+version = "2.2.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "plone-base" },
+ { name = "plone-resource" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f8/70/440beb1ccd62e733701a369861e26d264b3ee88fdc1806a6f2b39b8551c4/plone_staticresources-2.2.5.tar.gz", hash = "sha256:a5ae4f9d9f7394d007d0760bfc66884261ae20f46497bafb735d395936842d0c", size = 11617969 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1f/5d/e17170b85c4b8aa8204dc5ab30c3d2c4858cf8f6e17dd3e1df01ab2a6e1a/plone_staticresources-2.2.5-py3-none-any.whl", hash = "sha256:0661d8b6ea2565de8a1b3588125d7df5ed173cc948c3168720231c08af704766", size = 14391229 },
+]
+
+[[package]]
+name = "plone-stringinterp"
+version = "2.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "plone-memoize" },
+ { name = "products-plonepas" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5a/21/050abe093d251bef6c323191e09bf19bd62b53036f9e0922c8b987515b65/plone.stringinterp-2.0.2.tar.gz", hash = "sha256:06cbdd71734cf75ceed7c899bb26e98946868eb021f81b1bac9be15c6528bf05", size = 25179 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/4f/b2/3ba81bf5fdeeeca3ed80a2918f5eae98cad35491d9188fee37b5f2b9f4fe/plone.stringinterp-2.0.2-py3-none-any.whl", hash = "sha256:da5a65284f3fb1e787a8dde2984ce3df1ba5b8af7f05fbc57c3beac9c0f2e227", size = 23424 },
+]
+
+[[package]]
+name = "plone-subrequest"
+version = "2.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "plone-protect" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-globalrequest" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/99/b3/b368c5f211ff058f1953ff4d96d103edc6ee718591b385e5605567927950/plone.subrequest-2.0.5.tar.gz", hash = "sha256:a923e5b089737b0d631631885d6fd4f1468f988ebe98910e4a2ca8cfca4cd953", size = 25934 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ae/27/3ac7bbe6f2d0a40abea7f3490e04cb0f7b4083f7b062ab92f68142718f81/plone.subrequest-2.0.5-py3-none-any.whl", hash = "sha256:495999deb3f8b9ba3ff900047648c71fda7b803ddd07a463c0fe5ddb50182ffc", size = 14631 },
+]
+
+[[package]]
+name = "plone-supermodel"
+version = "2.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "setuptools" },
+ { name = "z3c-zcmlhook" },
+ { name = "zope-component" },
+ { name = "zope-deferredimport" },
+ { name = "zope-dottedname" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/4b/af/297a6bb49ecd98841c3c41ce2cca2c1dbe5d500b50fe4778e103ae02716d/plone.supermodel-2.0.4.tar.gz", hash = "sha256:123d7087b400eb5325fbc6b09d3bbd53dc2b6a2d1a26bed343465a0aa667fae1", size = 46757 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/40/2f/4f4265a2f9de7654035624ad0cf177b9cb8c0d4027b912d2263ea45bf81c/plone.supermodel-2.0.4-py3-none-any.whl", hash = "sha256:d0f12f158e052831ace5369039f937a561cff4ed632a41cc51faf6ebca5dda2b", size = 45151 },
+]
+
+[[package]]
+name = "plone-testing"
+version = "9.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/53/3e/9ff41b9eb956085925901b0b28b817e794cd43a70e6453e265aad5438039/plone_testing-9.0.5.tar.gz", hash = "sha256:f5a3897d42c3a8155f7072b8ccd2f48d681953ad356c23c9b10a1c0fc124f579", size = 163291 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/d1/dac3358aa03d0a7c0cb90ac017257e32b83d6ab440577e0a11c3fe04457d/plone_testing-9.0.5-py3-none-any.whl", hash = "sha256:ef3ef1a0ebacb8ff06c2f8165a445c5765f902e463116fb2085ff2f4011cfaf1", size = 121548 },
+]
+
+[package.optional-dependencies]
+security = [
+ { name = "zope-security" },
+]
+zca = [
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-event" },
+]
+zodb = [
+ { name = "zodb" },
+]
+
+[[package]]
+name = "plone-theme"
+version = "4.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0c/c2/803e776ee6f3de6a0de7b3333996416ca7b4829088c42d57c6f6aef2a33c/plone_theme-4.0.3.tar.gz", hash = "sha256:7bea16c0539238b06f4470d6040ab726686260c335291349b2c6685860748cd4", size = 18786 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/48/37/d97099c056413346fe58227a5ecfd61eedb93789ef07042331e6a9554922/plone.theme-4.0.3-py3-none-any.whl", hash = "sha256:6fb9509dd76db94a368c60bc39dfbe5240558002f810f5ef75b2d1fca7302bf1", size = 11235 },
+]
+
+[[package]]
+name = "plone-transformchain"
+version = "3.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2b/a8/5cd404b44a910163025fb56a05667a5a5ef70874079c7cacee447d94f0d4/plone.transformchain-3.0.1.tar.gz", hash = "sha256:5cf9b0168bb13cb057ee6f2eeebd5d3930a8124fc5739d8f185af3c4e4dff7c0", size = 13522 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/59/ff/fee6e82c73e2ea5627660651934e2c4c512817b0371d64f9b3857fdf6178/plone.transformchain-3.0.1-py3-none-any.whl", hash = "sha256:cb6e13a2535a2d38a2c24c94c941e005677e0a5a6d39d44e04edeab9e2c34b8a", size = 11140 },
+]
+
+[[package]]
+name = "plone-uuid"
+version = "2.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "setuptools" },
+ { name = "zope-browserpage" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-publisher" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b7/7e/92e01de3c61b56f592b166d38d1c6fc2b437d5e9385422a23b1726d9d136/plone.uuid-2.0.1.tar.gz", hash = "sha256:4c6e75183319484e90e0c3a6634e3322f99bc8b4f35733119d48c361a3407182", size = 11825 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/62/5b/b0d23f384286dbaae59b32459ae7444b5ca2a44ac149eeef782124ec352d/plone.uuid-2.0.1-py3-none-any.whl", hash = "sha256:a0ace249a7549b81357d2d5a06d022629ff8ac9d388e6ef0f5b8fc70f9f8928e", size = 8194 },
+]
+
+[[package]]
+name = "plone-volto"
+version = "5.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "collective-monkeypatcher" },
+ { name = "plone-api" },
+ { name = "plone-app-caching" },
+ { name = "plone-distribution" },
+ { name = "plone-restapi" },
+ { name = "products-cmfplone" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a3/e7/694e8d7ad5f56ff35d9aec6835f9acb9527be0a8d92653f3862ab15fb506/plone_volto-5.0.4.tar.gz", hash = "sha256:c31c19bfb3b6bf5a6de674cc598bd678e58990cc692783f25c0b147e92de0b5b", size = 260121 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/58/44/f7dc93634da374263dd79ed533a63a188601621508ddc444c187bdb482da/plone_volto-5.0.4-py3-none-any.whl", hash = "sha256:34d2ab40e78149db12ccdbfdea5c25207b89acc8bf07123913b656f8cbb54300", size = 268268 },
+]
+
+[[package]]
+name = "plone-z3cform"
+version = "2.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-batching" },
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope" },
+ { name = "zope-browserpage" },
+ { name = "zope-pagetemplate" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/3f/8a/42ef601f9a3c15805d243e5d0b4c3350c40b0926f2089f6d1d8de5f1380d/plone_z3cform-2.0.4.tar.gz", hash = "sha256:f3172c8993b77bba2985dfbe7f6e8141f106a7816a5433e5b4ecf94066a8c584", size = 90126 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d0/0b/10f6dc263d18a4e5667f6d7ae231e3603393bae170b14948023c5ff7f74c/plone.z3cform-2.0.4-py3-none-any.whl", hash = "sha256:05191ff968eb5babdfa48adfe61575aefc4afb280ff3039eef1aa8510d395710", size = 89883 },
+]
+
+[[package]]
+name = "plonegovbr-socialmedia"
+version = "2.0.0a5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-api" },
+ { name = "plone-restapi" },
+ { name = "plone-volto" },
+ { name = "products-cmfplone" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/83/2b/451573a1e9b2eb8046d720f8bfebf3729f80a33b87c75e306b41dc86861d/plonegovbr_socialmedia-2.0.0a5.tar.gz", hash = "sha256:453413ab0afa5ffd31691aba770fab6059dd3723ad2c860327e063b1197bc986", size = 27534 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0e/68/1aa61ef2b1bb3ea783eb679036a5ce6c8f9389e4fb75fb1d33ca09374893/plonegovbr_socialmedia-2.0.0a5-py3-none-any.whl", hash = "sha256:446e6ca425edd7ee1e0b41a3669438043fe7d06aa599ecfd7d601c5400c9bd30", size = 37596 },
+]
+
+[[package]]
+name = "plonetheme-barceloneta"
+version = "3.2.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-app-theming" },
+ { name = "plone-resource" },
+ { name = "plone-theme" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/af/1e/f36783e372fc73f8fb37b3e248c571da0445474910f228b5b9ffd536edbe/plonetheme_barceloneta-3.2.3.tar.gz", hash = "sha256:a4f46c805528a435ca8cecb2639e171cfd71a40f85cee80f8ebc3b1956f77d9b", size = 6135597 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/53/7f/081e10115aacdd58ec6255430d07f6cf695889dd814243ede0f6d1d5d97d/plonetheme.barceloneta-3.2.3-py3-none-any.whl", hash = "sha256:a2da8cb9eb407cdb184d5b3cbc1f2d592fda45ffb617dae243f1074e2b01635a", size = 6124323 },
+]
+
+[[package]]
+name = "pluggy"
+version = "1.5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 },
+]
+
+[[package]]
+name = "plumber"
+version = "1.7"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/94/f6/dba35af235a1fa6faa2dd84a67b0ecc49ac1b5c41eb44c354282367fb7f3/plumber-1.7.tar.gz", hash = "sha256:bde8d6323a8b3bdfc49ae3fa054c0801408a09a2c37e319ae9f0a4d49e4d5a23", size = 40414 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/84/53/e24f1e2e4263e9db0044c95c4302b7bc7f9f53c7cfe30bd19873199c02d1/plumber-1.7-py3-none-any.whl", hash = "sha256:4e734ce006b2b4367ce6f7e22c854f434f09eebfe9679b91758745c6184ddc11", size = 25295 },
+]
+
+[[package]]
+name = "products-btreefolder2"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "btrees" },
+ { name = "extensionclass" },
+ { name = "persistence" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-container" },
+ { name = "zope-event" },
+ { name = "zope-lifecycleevent" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/33/3c/04213c526ab419f58b774535190a79d7ccafac080851ec194d848f49a25f/Products.BTreeFolder2-5.1.tar.gz", hash = "sha256:baf2c878088731b838012a34e69190a938407677f933fdcaa70db398996df080", size = 19459 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1a/f2/404b2cecff29b8267f854dbcd234d53c690f00654c41d2a9c385075ecec8/Products.BTreeFolder2-5.1-py3-none-any.whl", hash = "sha256:3fbd9bcd2b2f22d4f158beee3cf41ad7b98c945718bed0a81a5ebdc48ad6dabd", size = 17782 },
+]
+
+[[package]]
+name = "products-cmfcore"
+version = "3.7"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "docutils" },
+ { name = "five-localsitemanager" },
+ { name = "products-btreefolder2" },
+ { name = "products-genericsetup" },
+ { name = "products-mailhost" },
+ { name = "products-pythonscripts" },
+ { name = "products-standardcachemanagers" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-datetime" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fd/87/19165fb21d191fe4c3b7551d2e291cabd1ac009397a7a14363aff1133c23/products_cmfcore-3.7.tar.gz", hash = "sha256:9672575118c5a521f9ed4154567b3087d7016d7fdaf39388ed42b92a5f1385f9", size = 308107 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9c/dd/6ee5e7de816e27030c9873e8deb511e547339a7392306b8bfe22f92834e3/Products.CMFCore-3.7-py3-none-any.whl", hash = "sha256:dbde1cb9b5adcfca144d56fd9e84239dec4fbec4c4f4be73065a51b5abb71178", size = 427044 },
+]
+
+[[package]]
+name = "products-cmfdifftool"
+version = "4.0.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "products-genericsetup" },
+ { name = "products-portaltransforms" },
+ { name = "setuptools" },
+ { name = "z3c-relationfield" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a7/c8/6b863fd370fdddef90cbd729fefc14c3bccc0667a80b0a47079f5d8c3a32/products_cmfdifftool-4.0.4.tar.gz", hash = "sha256:3865971f0d147694fbc470e60a33777f9361995dd59ed3666db6193d39368b44", size = 47702 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5c/57/b5d989e4bbb6739de8d4ee7a5c4c9c1b9267270b738233f7ae52f8396673/Products.CMFDiffTool-4.0.4-py3-none-any.whl", hash = "sha256:202670342365cfc600d312976fd33814a7b56f0bde39d7aaa47ab8a0d0baca00", size = 48167 },
+]
+
+[[package]]
+name = "products-cmfdynamicviewfti"
+version = "7.0.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/60/23/7cf0b669f3185f3edab5935e0cb54b59c541f6cbff04a6c3a012b8c630e2/Products.CMFDynamicViewFTI-7.0.2.tar.gz", hash = "sha256:e0a31489e8d2cd42733afa518906ec7cb73f38fb84e977fbed1c4e4fb39877b1", size = 27115 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2c/62/cddf8b99723e9378f6b748d3e61f62a40161c7cbbe62ac7cf58ba068c05f/Products.CMFDynamicViewFTI-7.0.2-py3-none-any.whl", hash = "sha256:97655971d97f0d0b9ee9b977850157ff071384662ec5c5356d8231dd4c394057", size = 23310 },
+]
+
+[[package]]
+name = "products-cmfeditions"
+version = "4.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "missing" },
+ { name = "persistence" },
+ { name = "plone-folder" },
+ { name = "plone-locking" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfdifftool" },
+ { name = "products-cmfuid" },
+ { name = "products-genericsetup" },
+ { name = "products-statusmessages" },
+ { name = "products-zopeversioncontrol" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-copy" },
+ { name = "zope-dottedname" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/41/16/22973605e9076fd06c1ee8058b64671eea3f730207a7b9346f62868003c4/products_cmfeditions-4.0.5.tar.gz", hash = "sha256:2032c6b0820b81c63ddd21887582404af5046c2e4ad4cc1924e191dda3ade8f0", size = 1768307 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f9/ac/922dfa85b90df72ffe4c8389286ff10e95acfd16aacd21399b3081bae3e4/Products.CMFEditions-4.0.5-py3-none-any.whl", hash = "sha256:3f12fa059d48e45d0dcd7e288419085c76a43006a87bc20b9a4461d233ece685", size = 245464 },
+]
+
+[[package]]
+name = "products-cmfplacefulworkflow"
+version = "3.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "persistence" },
+ { name = "plone-base" },
+ { name = "products-cmfcore" },
+ { name = "products-cmfplone" },
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5f/9e/76d03ae32900577296f683115adb4439508c9503fb0173092ac14942ca1d/products_cmfplacefulworkflow-3.0.5.tar.gz", hash = "sha256:6fb53a37175f4e3181ad7bddd3aa5414bc2e9831165fa21bd17d5ac1b53b296a", size = 50907 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/81/2f/b891d577cea0d3d1ec664b536917efd0edf9499a284c16c9d5308c4e8dce/Products.CMFPlacefulWorkflow-3.0.5-py3-none-any.whl", hash = "sha256:f99a8ec007b53bcfa6d0e93e924008c433d19917cbd22494ef2b92b2b4dbf82b", size = 64211 },
+]
+
+[[package]]
+name = "products-cmfplone"
+version = "6.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "borg-localrole" },
+ { name = "five-customerize" },
+ { name = "lxml" },
+ { name = "packaging" },
+ { name = "plone-app-content" },
+ { name = "plone-app-contentlisting" },
+ { name = "plone-app-contentmenu" },
+ { name = "plone-app-contentrules" },
+ { name = "plone-app-contenttypes" },
+ { name = "plone-app-customerize" },
+ { name = "plone-app-dexterity" },
+ { name = "plone-app-i18n" },
+ { name = "plone-app-layout" },
+ { name = "plone-app-linkintegrity" },
+ { name = "plone-app-locales" },
+ { name = "plone-app-portlets" },
+ { name = "plone-app-redirector" },
+ { name = "plone-app-registry" },
+ { name = "plone-app-theming" },
+ { name = "plone-app-users" },
+ { name = "plone-app-uuid" },
+ { name = "plone-app-viewletmanager" },
+ { name = "plone-app-vocabularies" },
+ { name = "plone-app-workflow" },
+ { name = "plone-app-z3cform" },
+ { name = "plone-autoinclude" },
+ { name = "plone-base" },
+ { name = "plone-browserlayer" },
+ { name = "plone-contentrules" },
+ { name = "plone-folder" },
+ { name = "plone-i18n" },
+ { name = "plone-indexer" },
+ { name = "plone-intelligenttext" },
+ { name = "plone-locking" },
+ { name = "plone-memoize" },
+ { name = "plone-outputfilters" },
+ { name = "plone-portlet-collection" },
+ { name = "plone-portlet-static" },
+ { name = "plone-portlets" },
+ { name = "plone-protect" },
+ { name = "plone-resource" },
+ { name = "plone-schema" },
+ { name = "plone-session" },
+ { name = "plone-staticresources" },
+ { name = "plone-theme" },
+ { name = "plonetheme-barceloneta" },
+ { name = "products-cmfeditions" },
+ { name = "products-dcworkflow" },
+ { name = "products-extendedpathindex" },
+ { name = "products-isurlinportal" },
+ { name = "products-mimetypesregistry" },
+ { name = "products-plonepas" },
+ { name = "products-portaltransforms" },
+ { name = "products-siteerrorlog" },
+ { name = "products-statusmessages" },
+ { name = "setuptools" },
+ { name = "webresource" },
+ { name = "zope", extra = ["wsgi"] },
+ { name = "zope-app-locales" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-deferredimport" },
+ { name = "zope-deprecation" },
+ { name = "zope-dottedname" },
+ { name = "zope-i18n" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-structuredtext" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ab/1a/97a3c8ddffc66ec80b22075db664d224988205d3973bb20ed79234bd0f66/products_cmfplone-6.1.1.tar.gz", hash = "sha256:9e1bb2959c8d42fa22e12df34d238a6a1e7fe770c4c319c17ab7b1feab054de8", size = 871334 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c0/16/71b3eaeaa7a0640a3e5d1e06b20a0c36830f850221e90edc64b4ff8a3c6d/products_cmfplone-6.1.1-py3-none-any.whl", hash = "sha256:4c208f305975fde4aeef6c2b5c83090e51f572ac79ce7450d1a0ef68f6d761e8", size = 872177 },
+]
+
+[package.optional-dependencies]
+test = [
+ { name = "gunicorn" },
+ { name = "lxml" },
+ { name = "plone-app-robotframework" },
+ { name = "plone-app-testing" },
+ { name = "robotframework-debuglibrary" },
+ { name = "zope-globalrequest" },
+ { name = "zope-testing" },
+]
+
+[[package]]
+name = "products-cmfuid"
+version = "4.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/77/f5/9bd554fd5adfc29ab2d49eb027b9852ff9277ef657cf627d1db396c33083/Products.CMFUid-4.2.tar.gz", hash = "sha256:74bb13a8189a4308cdd07ab6b63a6132f8e08c9810d69df936c94bfd57d2f942", size = 23950 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ba/f7/5a022443b99fc39772d3c953726f27d0006561e217632f00344298466c04/Products.CMFUid-4.2-py3-none-any.whl", hash = "sha256:efb46b10dd55d0c2f207c25c4534df20b70492eb2e4a5b75d0f168961d4560fe", size = 25519 },
+]
+
+[[package]]
+name = "products-daterecurringindex"
+version = "3.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "plone-event" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zodb" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/60/96/66362e6e0db7b5badb40bf0a5703529de14085ad8869033ac98fdc8add37/Products.DateRecurringIndex-3.0.1.tar.gz", hash = "sha256:1c40f632f7b61aba05d1816935404887d0ebd030b68109c3cc67887e4d1e3df8", size = 11201 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fc/7b/f79181c474322905d096d319f2036df537529707c395730dade90b9d2f33/Products.DateRecurringIndex-3.0.1-py2.py3-none-any.whl", hash = "sha256:cf471f239d24fe97c0959cd3dc0e5daed7cd480c9394182c6a263acd81e9993e", size = 12556 },
+]
+
+[[package]]
+name = "products-dcworkflow"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "products-externalmethod" },
+ { name = "products-genericsetup" },
+ { name = "products-pythonscripts" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/54/ce/3be2b5e4460df7f9d83dbfe25d6224c425bd47880328267a06b062c3ce79/Products.DCWorkflow-3.0.tar.gz", hash = "sha256:70a5ae243c9fcffd3a9e85afa7eabdcc20a597d2844d1facd61a2fcccd1835d8", size = 85089 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/24/bc/ef334b772b4e2f98e315556a794aca384fa74794b0876c984920c97729ee/Products.DCWorkflow-3.0-py3-none-any.whl", hash = "sha256:e47d90920b98f816fd0eb9c94a6954b1ed8f669b819eb8d51b5dbd8d610e8dc1", size = 83466 },
+]
+
+[[package]]
+name = "products-extendedpathindex"
+version = "4.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "six" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b7/40/8d98b61ee6b4545a6d5ed8354bccd506fa301a0e51feccccf8707f28164b/Products.ExtendedPathIndex-4.0.1.tar.gz", hash = "sha256:5049bff145379d7db4a247dbf3661d1ab7cff2eeb02830a37e5a53c6d0863c63", size = 23619 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c9/b8/d2a05d27a9a36e2202005a6323670ee0166f60670aaeefd9cfcb65dcd84e/Products.ExtendedPathIndex-4.0.1-py2.py3-none-any.whl", hash = "sha256:92f826b7b129f9dcf8fb662f8c7504d07a5ff64fc38f3ecdc85376298bf726bd", size = 15432 },
+]
+
+[[package]]
+name = "products-externalmethod"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "extensionclass" },
+ { name = "persistence" },
+ { name = "setuptools" },
+ { name = "zodb" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/6e/39/01bec8303f66079f1443af9948f9ce273903647cce0e3f11acde666b4b41/Products.ExternalMethod-6.0.tar.gz", hash = "sha256:d1b04974f0cf051e960647885b428e2a5c1d8110aae9dc48a562359fe796bcd7", size = 12281 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9b/c5/dd955c130aea558285f29136fe2fced8e04ea411ae38bfb9cca77e41efbc/Products.ExternalMethod-6.0-py3-none-any.whl", hash = "sha256:4d1917b4fc40e46185be1f630c9ed5d0759fa96924e981863e35de7fc9adeffd", size = 12186 },
+]
+
+[[package]]
+name = "products-genericsetup"
+version = "5.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "five-localsitemanager" },
+ { name = "packaging" },
+ { name = "products-pythonscripts" },
+ { name = "products-zcatalog" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/3f/32/87b105bbbf32512aba30241131ccacf660eefe565aa710f06e561cd371e1/products_genericsetup-5.0.0.tar.gz", hash = "sha256:580c67fa7a44ea7ca305ea680bb786233bb7b5e393a3ead51fdf69a1e04f1425", size = 152004 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cd/ab/9dc6a698d3b27ad9c3dee6a3c4d30893bc3c71a0204119e286438cdf3174/Products.GenericSetup-5.0.0-py3-none-any.whl", hash = "sha256:3a73232da0b36467fd006f95a1c8f5842385272f307bea77e21f1058268f018f", size = 179665 },
+]
+
+[[package]]
+name = "products-isurlinportal"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-base" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/55/ab/b88b2f36d6c6ed73c5a83c79e7a10a113e1ea59572c845ecaa29b52bac24/products_isurlinportal-3.0.0.tar.gz", hash = "sha256:6340b31897b3111bccef592e6c31a25be41888e8ab2866a49aaf279863855293", size = 15274 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/da/d7/082c0b72256aee7d801af44228410c110d232b9a382c55867e23e6975f1f/Products.isurlinportal-3.0.0-py3-none-any.whl", hash = "sha256:da340f01befef8c79792aa0e7ad3b5175be942360a7fa92cb5f155d75abd5e93", size = 10573 },
+]
+
+[[package]]
+name = "products-mailhost"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "datetime" },
+ { name = "documenttemplate" },
+ { name = "extensionclass" },
+ { name = "persistence" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-deferredimport" },
+ { name = "zope-interface" },
+ { name = "zope-sendmail" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/12/aa/f6d280c1d4801176fd88e3f859869fa69c57a6f26b6c657786367b06fa2a/products_mailhost-6.0.tar.gz", hash = "sha256:e82983a6c5b48a4555e4335c9110ccb046d52aa3c01ca2ba5be38eca51ddc116", size = 27538 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dc/95/f6fc197262ec5f8d799472b77ad796a7cd16e6a27835f1c3618d01d21269/Products.MailHost-6.0-py3-none-any.whl", hash = "sha256:c042dbea252b53db0b42a2a61e1967c9665facdd95a37717207e5d56c9b84c92", size = 29977 },
+]
+
+[[package]]
+name = "products-mimetypesregistry"
+version = "3.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfcore" },
+ { name = "pywin32", marker = "sys_platform == 'win32'" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/53/73/415a2b83da722b288a5dc0435dc624c05ac1912d181cf642102995c3cf36/Products.MimetypesRegistry-3.0.1.tar.gz", hash = "sha256:49c17f1f4ecc8e84b190e6bb53e575331e7b7faedc2cd65ce8557bf2bc1acdbe", size = 417884 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2d/3f/e0be74801a8ec19e914b2a8b448103571dcfb89c5a62e090cca1173e04e1/Products.MimetypesRegistry-3.0.1-py3-none-any.whl", hash = "sha256:6a6c444ad7ee1b7ab8f69cb3adc4d8434547c54255769ed33e69f6e9bf48fffa", size = 436060 },
+]
+
+[[package]]
+name = "products-plonepas"
+version = "8.0.5"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pillow" },
+ { name = "plone-base" },
+ { name = "plone-i18n" },
+ { name = "plone-memoize" },
+ { name = "plone-protect" },
+ { name = "plone-registry" },
+ { name = "plone-session" },
+ { name = "products-btreefolder2" },
+ { name = "products-genericsetup" },
+ { name = "products-pluggableauthservice" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/00/cb/5dc4c3e128de0ac3976a3ba34707c1254f22bf7057d5a466b82ca1896725/products_plonepas-8.0.5.tar.gz", hash = "sha256:11e88e3b979cec5937075804d78c98b565a07b1f6e41543096eaf7efffcf36c1", size = 128093 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3c/07/52323525f354905a20da3d2a4297231aacdf576274fce580d00263023348/Products.PlonePAS-8.0.5-py3-none-any.whl", hash = "sha256:ad16e9f83161a40ecc13ed11875b88ab3b809c866e05fa08503935e4a8ee18e2", size = 120468 },
+]
+
+[[package]]
+name = "products-pluggableauthservice"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "products-genericsetup" },
+ { name = "products-pluginregistry" },
+ { name = "products-sessions" },
+ { name = "products-standardcachemanagers" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b9/34/011daf7976ac65798b2289a6d756c9e72dce30b313641ff68e062fcb3f9c/Products.PluggableAuthService-3.0.tar.gz", hash = "sha256:e5a24ea66fedfeb9cff24b2fa1369fa492f28470c22a8ac22126f474b8360a63", size = 166772 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2b/91/9bd580edd17bd2594008ee0b76dd5c158aa4b125486db0b11c32c29a106a/Products.PluggableAuthService-3.0-py3-none-any.whl", hash = "sha256:2aea4cfbc003ab3962a378970333e5588312e29fe710b1c3150708e183bd2d93", size = 219822 },
+]
+
+[[package]]
+name = "products-pluginregistry"
+version = "2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-genericsetup" },
+ { name = "setuptools" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/64/6c/96ba587dd493eb3b858de6cf3ade0d027f21d3d7d8daa7193055dd022a74/Products.PluginRegistry-2.0.tar.gz", hash = "sha256:7f7394c3ed7f40731133face0bc45f166875f3abb4fe832b46be983d9adf38a9", size = 23507 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0d/c5/98a8a34c4b3048993aa650b960ddb397bb3fd5582d5307e114ae195d99d4/Products.PluginRegistry-2.0-py3-none-any.whl", hash = "sha256:d50a2e6327062a6fa5502268ec47e6fcd111ddf754f17232e6922675373cd456", size = 27335 },
+]
+
+[[package]]
+name = "products-portaltransforms"
+version = "4.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "documenttemplate" },
+ { name = "docutils" },
+ { name = "lxml" },
+ { name = "lxml-html-clean" },
+ { name = "markdown" },
+ { name = "persistence" },
+ { name = "persistent" },
+ { name = "pillow" },
+ { name = "plone-base" },
+ { name = "plone-intelligenttext" },
+ { name = "plone-registry" },
+ { name = "products-cmfcore" },
+ { name = "products-genericsetup" },
+ { name = "products-mimetypesregistry" },
+ { name = "setuptools" },
+ { name = "zope" },
+ { name = "zope-structuredtext" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b9/f3/93425ee95be5121203f842363e4f2a8a184016351334e0a5b5f8e5efc8fb/products_portaltransforms-4.1.1.tar.gz", hash = "sha256:b710a5739d837f2e9e106ad9e81c392a34584c7cd63c75bdc631e47147bb56ca", size = 204458 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/32/7b/f97555f832f8045ce87bdf2097fc7116a73b9bbe32b9ec4aa90689667f8d/Products.PortalTransforms-4.1.1-py3-none-any.whl", hash = "sha256:84f329d76d56827058882ec27749363c0eace938b71b91ff4641385b7cf1a45e", size = 220516 },
+]
+
+[[package]]
+name = "products-pythonscripts"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "datetime" },
+ { name = "documenttemplate" },
+ { name = "restrictedpython" },
+ { name = "setuptools" },
+ { name = "zexceptions" },
+ { name = "zope" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2f/88/7028e9c4b0b6a6ad40651beed8fecc0b9d907c6561d444a54b8c49ef2b41/Products.PythonScripts-5.1.tar.gz", hash = "sha256:8b9d0dea6473c9640720f1b8afb1bf6e62993399e43ffbbc1305b98c8a5dd475", size = 30207 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/01/2e/5c69043d3dc0a4b34be952e07740cc2706caac3266482fca73c99f9e9380/Products.PythonScripts-5.1-py3-none-any.whl", hash = "sha256:56a914da0e7b694ee3864531d9e98096a881323a6e16549a454402590608081d", size = 34215 },
+]
+
+[[package]]
+name = "products-sessions"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "persistence" },
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zodb" },
+ { name = "zope" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c3/de/65067f856ca267b9faae8dadede93ad8010377b6b9163ad7bdab40b5a4a0/Products.Sessions-5.0.tar.gz", hash = "sha256:f493d501a051c98c92fb9be27e272516c8c34c62e077ed357c15c39cdc8db57b", size = 59780 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a5/7d/4375fe288274730ff7c215376bb976c42c9c5874113f905f4094f7bd2948/Products.Sessions-5.0-py3-none-any.whl", hash = "sha256:4b4e7f56c7cb6560becc90bf04e23264f76f570be08469c923a0ee7b4ce2dada", size = 73835 },
+]
+
+[[package]]
+name = "products-siteerrorlog"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zexceptions" },
+ { name = "zope" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c2/4c/13cf15d3d4d1e5fffc14eb6e7ed30dedb46ea7faaa02031c16756c26bc20/Products.SiteErrorLog-6.0.tar.gz", hash = "sha256:4a202dc68ae111f19994c67c0f37235c8fb8a64c942c9b7a7903fef32badf87d", size = 17367 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/80/9e/7c1401265e0fe238be09cd902db2830ce2f9cfa13ac053ca6986dfd02716/Products.SiteErrorLog-6.0-py3-none-any.whl", hash = "sha256:e3880bf6faa01d829534f0ab6862aefc709d9b1e10c120a56ade197ee2c91af5", size = 18315 },
+]
+
+[[package]]
+name = "products-standardcachemanagers"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zope" },
+ { name = "zope-component" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/6e/47/4171b0075a5684f68868b020a5ec4696828e8d932a34c1e339e9167e1c7f/Products.StandardCacheManagers-5.0.tar.gz", hash = "sha256:d4cb2a427d3ec36fe60c872a1dd36d03cf277ebe5ef02beaf7d15ea49f7c2e3c", size = 20031 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5e/5e/0baea7276be3753cbfa38bd005fd1b052dcf6fad20aa9676460b79bc979e/Products.StandardCacheManagers-5.0-py3-none-any.whl", hash = "sha256:e401119a4ab5290b377726297b5e0739c382aea58fada192b101cd88f09aa921", size = 24963 },
+]
+
+[[package]]
+name = "products-statusmessages"
+version = "5.0.6"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-annotation" },
+ { name = "zope-i18n" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/57/04/ca2ad4c51d3e900f75a07b79a74652c88ee866ccc4c9d0ab9be40ea0d20c/Products.statusmessages-5.0.6.tar.gz", hash = "sha256:fc3527521a27ff1340eb90dcb0bce2f5ae45296fe44b6461d1a2aad147aea88f", size = 14998 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b5/6e/9f338ce65ff8220a69530d56d90415a0dd5d4b8ca1ea7c80d4d745230d0f/Products.statusmessages-5.0.6-py3-none-any.whl", hash = "sha256:6642fab1bde75c6a6923dc7700310bcbf5eef3cbc6409165ca7c45d81c0a37b8", size = 11770 },
+]
+
+[[package]]
+name = "products-zcatalog"
+version = "7.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "btrees" },
+ { name = "datetime" },
+ { name = "documenttemplate" },
+ { name = "extensionclass" },
+ { name = "missing" },
+ { name = "persistence" },
+ { name = "record" },
+ { name = "restrictedpython" },
+ { name = "setuptools" },
+ { name = "zexceptions" },
+ { name = "zodb" },
+ { name = "zope" },
+ { name = "zope-deferredimport" },
+ { name = "zope-dottedname" },
+ { name = "zope-globalrequest" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/96/82/c5900030cdd313c8ee2a0f75f179b309eef6dcd41ec6b49e7d34171c3f79/Products.ZCatalog-7.1.tar.gz", hash = "sha256:e14088123e1da571c510bfa563b2a8e1738dbf4007bb5883daf0e668e0231ab7", size = 183168 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/12/7d/541a4737b73ef1affb7cabf80cffea830e3dd52b76e101826d8bd2e14f7b/Products.ZCatalog-7.1-py3-none-any.whl", hash = "sha256:6c8612c4a7500517f47d690f764e554da8aeac097b9b1de511cd9ca401b46245", size = 230481 },
+]
+
+[[package]]
+name = "products-zopeversioncontrol"
+version = "4.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "acquisition" },
+ { name = "datetime" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zodb" },
+ { name = "zope" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ae/24/0134f8a5222e3c14483c9df8cc23038ce60c8da855d022d46aa706dabf5f/Products.ZopeVersionControl-4.1.tar.gz", hash = "sha256:004b8157952c630b942c0c1deb7fc846d04dc7ab95797b452bf3ae35ae6bd96f", size = 34428 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a2/8a/3deb7b9810e531aaf667f769f2cc4c3f654bbc02aded9775699f10993d34/Products.ZopeVersionControl-4.1-py3-none-any.whl", hash = "sha256:38b742008665bbd2022e4434bd0e0d5f273fbb9d92186878644cecdb07a18112", size = 52117 },
+]
+
+[[package]]
+name = "prompt-toolkit"
+version = "3.0.48"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "wcwidth" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2d/4f/feb5e137aff82f7c7f3248267b97451da3644f6cdc218edfe549fb354127/prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90", size = 424684 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a9/6a/fd08d94654f7e67c52ca30523a178b3f8ccc4237fce4be90d39c938a831a/prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e", size = 386595 },
+]
+
+[[package]]
+name = "protobuf"
+version = "5.29.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f7/d1/e0a911544ca9993e0f17ce6d3cc0932752356c1b0a834397f28e63479344/protobuf-5.29.3.tar.gz", hash = "sha256:5da0f41edaf117bde316404bad1a486cb4ededf8e4a54891296f648e8e076620", size = 424945 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dc/7a/1e38f3cafa022f477ca0f57a1f49962f21ad25850c3ca0acd3b9d0091518/protobuf-5.29.3-cp310-abi3-win32.whl", hash = "sha256:3ea51771449e1035f26069c4c7fd51fba990d07bc55ba80701c78f886bf9c888", size = 422708 },
+ { url = "https://files.pythonhosted.org/packages/61/fa/aae8e10512b83de633f2646506a6d835b151edf4b30d18d73afd01447253/protobuf-5.29.3-cp310-abi3-win_amd64.whl", hash = "sha256:a4fa6f80816a9a0678429e84973f2f98cbc218cca434abe8db2ad0bffc98503a", size = 434508 },
+ { url = "https://files.pythonhosted.org/packages/dd/04/3eaedc2ba17a088961d0e3bd396eac764450f431621b58a04ce898acd126/protobuf-5.29.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8434404bbf139aa9e1300dbf989667a83d42ddda9153d8ab76e0d5dcaca484e", size = 417825 },
+ { url = "https://files.pythonhosted.org/packages/4f/06/7c467744d23c3979ce250397e26d8ad8eeb2bea7b18ca12ad58313c1b8d5/protobuf-5.29.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:daaf63f70f25e8689c072cfad4334ca0ac1d1e05a92fc15c54eb9cf23c3efd84", size = 319573 },
+ { url = "https://files.pythonhosted.org/packages/a8/45/2ebbde52ad2be18d3675b6bee50e68cd73c9e0654de77d595540b5129df8/protobuf-5.29.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:c027e08a08be10b67c06bf2370b99c811c466398c357e615ca88c91c07f0910f", size = 319672 },
+ { url = "https://files.pythonhosted.org/packages/fd/b2/ab07b09e0f6d143dfb839693aa05765257bceaa13d03bf1a696b78323e7a/protobuf-5.29.3-py3-none-any.whl", hash = "sha256:0a18ed4a24198528f2333802eb075e59dea9d679ab7a6c5efb017a59004d849f", size = 172550 },
+]
+
+[[package]]
+name = "psycopg2"
+version = "2.9.10"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/62/51/2007ea29e605957a17ac6357115d0c1a1b60c8c984951c19419b3474cdfd/psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11", size = 385672 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3d/16/4623fad6076448df21c1a870c93a9774ad8a7b4dd1660223b59082dd8fec/psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067", size = 1025113 },
+ { url = "https://files.pythonhosted.org/packages/66/de/baed128ae0fc07460d9399d82e631ea31a1f171c0c4ae18f9808ac6759e3/psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e", size = 1163951 },
+ { url = "https://files.pythonhosted.org/packages/ae/49/a6cfc94a9c483b1fa401fbcb23aca7892f60c7269c5ffa2ac408364f80dc/psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2", size = 2569060 },
+]
+
+[[package]]
+name = "pycparser"
+version = "2.22"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 },
+]
+
+[[package]]
+name = "pyjwt"
+version = "2.10.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 },
+]
+
+[[package]]
+name = "pyotp"
+version = "2.9.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f3/b2/1d5994ba2acde054a443bd5e2d384175449c7d2b6d1a0614dbca3a63abfc/pyotp-2.9.0.tar.gz", hash = "sha256:346b6642e0dbdde3b4ff5a930b664ca82abfa116356ed48cc42c7d6590d36f63", size = 17763 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c3/c0/c33c8792c3e50193ef55adb95c1c3c2786fe281123291c2dbf0eaab95a6f/pyotp-2.9.0-py3-none-any.whl", hash = "sha256:81c2e5865b8ac55e825b0358e496e1d9387c811e85bb40e71a3b29b288963612", size = 13376 },
+]
+
+[[package]]
+name = "pysocks"
+version = "1.7.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725 },
+]
+
+[[package]]
+name = "pytest"
+version = "7.4.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+ { name = "iniconfig" },
+ { name = "packaging" },
+ { name = "pluggy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287 },
+]
+
+[[package]]
+name = "pytest-cov"
+version = "6.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "coverage" },
+ { name = "pytest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841 },
+]
+
+[[package]]
+name = "pytest-plone"
+version = "1.0.0a1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "plone-api" },
+ { name = "plone-app-testing" },
+ { name = "plone-base" },
+ { name = "plone-browserlayer" },
+ { name = "plone-dexterity" },
+ { name = "products-cmfplone", extra = ["test"] },
+ { name = "pytest" },
+ { name = "zope-component" },
+ { name = "zope-pytestlayer" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ab/47/bf502c1f2a60729892f7454cdd4b985a40307de64efc331544986c57ceaf/pytest_plone-1.0.0a1.tar.gz", hash = "sha256:aef180354ddadf0117d50e03991b6c8b70be78d0d7d54f4ef0ff001aeef3521a", size = 18843 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/81/2b/9d5eeafb3831344317b8e2fb3949b40f173a40a6b9b035e6cdb5f8cba3b8/pytest_plone-1.0.0a1-py3-none-any.whl", hash = "sha256:92b09ddff35cc086a50cb69f6d98852b74355b42f97cede1addf420ed9f0a590", size = 16247 },
+]
+
+[[package]]
+name = "python-dateutil"
+version = "2.9.0.post0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
+]
+
+[[package]]
+name = "python-gettext"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/c8/85df0d3956bebdbaff936df47a5705be9e0b42404589a07065a39c8324e5/python-gettext-5.0.tar.gz", hash = "sha256:869af1ea45e3dab6180557259824c2a62f1800e1286226af912431fe75c5084c", size = 9879 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0d/e7/70b80ec3480b9c453366a396e31eaa2f00b5a6824e1600d23f796e848b6b/python_gettext-5.0-py3-none-any.whl", hash = "sha256:083d4c72c5e72a6bd83b0570770792b9a1e572d8ab3e9cba554e0cd4781aa84a", size = 13086 },
+]
+
+[[package]]
+name = "pythonbrasil-site"
+source = { editable = "." }
+dependencies = [
+ { name = "collective-honeypot" },
+ { name = "collective-volto-formsupport" },
+ { name = "plone-api" },
+ { name = "plone-app-upgrade" },
+ { name = "plone-restapi" },
+ { name = "plone-volto" },
+ { name = "plonegovbr-socialmedia" },
+ { name = "products-cmfplone" },
+]
+
+[package.dev-dependencies]
+build = [
+ { name = "hatchling" },
+ { name = "wheel" },
+]
+container = [
+ { name = "plone-app-upgrade" },
+ { name = "psycopg2" },
+ { name = "relstorage" },
+ { name = "zeo" },
+]
+test = [
+ { name = "horse-with-no-namespace" },
+ { name = "mypy" },
+ { name = "plone-app-testing" },
+ { name = "plone-restapi", extra = ["test"] },
+ { name = "pytest" },
+ { name = "pytest-cov" },
+ { name = "pytest-plone" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "collective-honeypot" },
+ { name = "collective-volto-formsupport" },
+ { name = "plone-api" },
+ { name = "plone-app-upgrade" },
+ { name = "plone-restapi" },
+ { name = "plone-volto" },
+ { name = "plonegovbr-socialmedia", specifier = ">=2.0.0a5" },
+ { name = "products-cmfplone", specifier = "==6.1.1" },
+]
+
+[package.metadata.requires-dev]
+build = [
+ { name = "hatchling" },
+ { name = "wheel" },
+]
+container = [
+ { name = "plone-app-upgrade" },
+ { name = "psycopg2", specifier = "==2.9.10" },
+ { name = "relstorage", specifier = "==4.1.1" },
+ { name = "zeo", specifier = "==6.0.0" },
+]
+test = [
+ { name = "horse-with-no-namespace", specifier = ">=20250408.0" },
+ { name = "mypy", specifier = ">=1.15.0" },
+ { name = "plone-app-testing" },
+ { name = "plone-restapi", extras = ["test"] },
+ { name = "pytest" },
+ { name = "pytest-cov", specifier = "==6.1.1" },
+ { name = "pytest-plone", specifier = ">=1.0.0a1" },
+]
+
+[[package]]
+name = "pytz"
+version = "2024.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 },
+]
+
+[[package]]
+name = "pywin32"
+version = "310"
+source = { registry = "https://pypi.org/simple" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6b/ec/4fdbe47932f671d6e348474ea35ed94227fb5df56a7c30cbbb42cd396ed0/pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d", size = 8796239 },
+ { url = "https://files.pythonhosted.org/packages/e3/e5/b0627f8bb84e06991bea89ad8153a9e50ace40b2e1195d68e9dff6b03d0f/pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060", size = 9503839 },
+ { url = "https://files.pythonhosted.org/packages/1f/32/9ccf53748df72301a89713936645a664ec001abd35ecc8578beda593d37d/pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966", size = 8459470 },
+ { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384 },
+ { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039 },
+ { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152 },
+]
+
+[[package]]
+name = "record"
+version = "4.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "extensionclass" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ef/3f/199e693ffb884d68e912baae84f9467d58061081c5a7e92fa4077ebeed29/Record-4.1.tar.gz", hash = "sha256:3dac2d1f852ae50736abc464e0e098d41f8196366130108a302b039447837f10", size = 8038 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/94/2e/f3018733b29bd0420f8e2b876f42389206f9d01984a10ac0e062493eea97/Record-4.1-py3-none-any.whl", hash = "sha256:bdfe5e9da6d138f2e17732b39db5c2bdae049088dda09aad3bd74738f78e5a01", size = 6435 },
+]
+
+[[package]]
+name = "referencing"
+version = "0.35.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+ { name = "rpds-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/99/5b/73ca1f8e72fff6fa52119dbd185f73a907b1989428917b24cff660129b6d/referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", size = 62991 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/59/2056f61236782a2c86b33906c025d4f4a0b17be0161b63b70fd9e8775d36/referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de", size = 26684 },
+]
+
+[[package]]
+name = "relstorage"
+version = "4.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "packaging" },
+ { name = "perfmetrics" },
+ { name = "transaction" },
+ { name = "zc-lockfile" },
+ { name = "zodb" },
+ { name = "zope-dottedname" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/47/de/3dc088a83c74b4cb5824746d21d4c40b60a66de2d5c42d043080b841b459/relstorage-4.1.1.tar.gz", hash = "sha256:fd0069094732c98bdea1f4fb33e29a2ced0735368d4dee98644eaf974055ad5c", size = 2639326 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/99/a6/5ccfc55d8198a97e093f958ef241a77362791f84cd9dd6516bc126ee6478/RelStorage-4.1.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a8cb9cd56e8b726eef036afc35fc033e4a4634bdb074aee04a862c9beda69c68", size = 1375338 },
+ { url = "https://files.pythonhosted.org/packages/a0/e6/d599302d6ffcd307d61492cc6e90c94f31b3cba3540e8c826e3dce0e9388/RelStorage-4.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be730211c414e18fded900cf65860785cdd4213a87fedcd099a72b1f4697229", size = 1250862 },
+ { url = "https://files.pythonhosted.org/packages/3a/72/b37b9f2b83283d0b8dcf03c7ea942c9b2b2b6f5a41614ef98c3d57d07712/RelStorage-4.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fdd441ca38bc32adf84765a2e6382bf350003589a183f2712bc06bfd395063d", size = 1279136 },
+ { url = "https://files.pythonhosted.org/packages/fe/c3/adfadfbca3d3289f7be828893d9a84450f2a0ca2a521bff08314c056215a/RelStorage-4.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c451963cb0c3c759b2c4752930160888a4000429d40dbd14bcbebf3cc8da5f2", size = 1250113 },
+ { url = "https://files.pythonhosted.org/packages/15/19/f5b7253c2a174c3e70d141d5112e4cba6e46b73eacc1767e5e001a43ccdf/RelStorage-4.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecc4eb69c5c3ea3df9e99f4f41ecd5f4cabc55908e437edb2af38078746cd55d", size = 1260333 },
+ { url = "https://files.pythonhosted.org/packages/4b/08/4f5cbbb0192bd03f71d97013953dae7d15687ab9f6049da76c2c09e2c71c/RelStorage-4.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c5d21c2b9e390e0f210e78f0cb60c71526e281be3cf43501ad9b83dae654b9b", size = 1236224 },
+ { url = "https://files.pythonhosted.org/packages/eb/96/d8c7019916b5c73872fe5648d1100236d344305590458f3d9d05b607800b/RelStorage-4.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4d751b4c50f6393449a97c179d18c329eb3c68a6b02068c582cf9e56b7647e99", size = 1762044 },
+ { url = "https://files.pythonhosted.org/packages/8d/ee/70483358f5ab35b8cfb302d8bac7d28c7ab3d2694c0c0c1de113293cc0de/RelStorage-4.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0d88a9fd0c022dc045d8f57f0fded219c3e8e9ec38edc10e95a7baf6d16d5898", size = 1778757 },
+ { url = "https://files.pythonhosted.org/packages/60/76/39c02e4c72230bc61508268a0035d6be78b15896375da33a1c51796d5e34/RelStorage-4.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:10a9c046245088b51db2c4d952633d95b9b21f8bb2d68e2fe142dada45241b26", size = 1154341 },
+ { url = "https://files.pythonhosted.org/packages/be/69/fd04d715bc5f4db593e9a1f4247c8ae8f19f955a0a8225094ac10c9c2723/RelStorage-4.1.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0cb3543b4dc35a94dcd776cc2e053481498cfdff6c5fcd954b9e2d00fe8ffe55", size = 1375560 },
+ { url = "https://files.pythonhosted.org/packages/45/fd/04facf19d5c2ca0d34dc4d98917e5ae991df9653c39029eeafab5fe0f68c/RelStorage-4.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2ec8d4da74dc6cf86bcea42a0ad20957fd0dc8fc3d647ffe89bd723a5b30e01", size = 1249397 },
+ { url = "https://files.pythonhosted.org/packages/b5/ea/5b3ed72ee37194e77b33bd8d11539f41d94eb75fefdda0c7a64892e64db6/RelStorage-4.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b0766be81e7fb5c850a9b6ddc2d92814edda160257b4218bf6179d9edac37851", size = 1276808 },
+ { url = "https://files.pythonhosted.org/packages/e8/50/26b0325c33d7e80e8b425e7cb57eb57cb846518cd88567ec3d30869c4ca6/RelStorage-4.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21e4ebd3016efd9d73276136ba97d4f91f051e0df4c923f3d46e2c1389372f2c", size = 1249397 },
+ { url = "https://files.pythonhosted.org/packages/9a/ed/d25f5af65338a86cdf2526ce71bf79216243c4adbc45f4eed92b083b65a9/RelStorage-4.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:feb8e5c638957f420064813a2ce7654b533501b6c1747728b1a9e17c48b55ab0", size = 1259035 },
+ { url = "https://files.pythonhosted.org/packages/75/d1/2e8439462acabe3c5e2d11b6a390da448ae4220fad5e984fc1d807bed485/RelStorage-4.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef5cd899ee73d6ba61e5ce5aac78389e905f4dc1b0eb60617478090c9ca13576", size = 1235020 },
+ { url = "https://files.pythonhosted.org/packages/7e/a8/b1b3615a693f5aba557b2bf20b7e88e4d77810ce5e7dd87c8754ca68a9ef/RelStorage-4.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:b0188cb3db9f3af3031b62fa7d59d5b78881713727556667e1d639dc7a638b7c", size = 1760654 },
+ { url = "https://files.pythonhosted.org/packages/eb/1b/d9aec03dfe759fc27e3a6568ee3906e1666cbafd05a69df28b191193ab0e/RelStorage-4.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:f34ec8eda09317fb1326b52048083752972efe22644505d8ce22191eacf51a49", size = 1777033 },
+ { url = "https://files.pythonhosted.org/packages/1c/72/612d1cf15a4fa939584c88b59f99117655edcda3e793e0019329292b6723/RelStorage-4.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7c0c9c5e1b6cb457f1c0ba52a4e5f237181812c5853d21b49e4682388e9a58f", size = 1152667 },
+]
+
+[[package]]
+name = "repoze-catalog"
+version = "0.9.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zodb3" },
+ { name = "zope-component" },
+ { name = "zope-index" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/91/42/12833c4a1f0f546b9acfc95318d23c0fc5ece9bd318dae5c9fa339c0340b/repoze.catalog-0.9.0.tar.gz", hash = "sha256:7760813dac15128a55016a8367c87a2c6045aafdc8137aa72ea01dc36d442728", size = 101757 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/73/09/6445c23bc7b04951b88e02fcaa8cb665f95812d290f0650bbd05c6525dc6/repoze.catalog-0.9.0-py3-none-any.whl", hash = "sha256:3434026513f67e442be4ba0ff7aedc4264b6e936226051b79b53bf46d2a82792", size = 87880 },
+]
+
+[[package]]
+name = "repoze-xmliter"
+version = "1.0b1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/09/11/219b769637c069dafae6c38e17089b52c5b14279b86c8939c11c74a2a199/repoze.xmliter-1.0b1.tar.gz", hash = "sha256:ad903bc9d7559f546eb7e8ca470fd562fa636df411f9ed3bb4e9a17b14a931d1", size = 14566 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fd/a9/9ae630e58847df8842cb7c54a6c013950394364be4710efc3821aa37a7be/repoze.xmliter-1.0b1-py3-none-any.whl", hash = "sha256:639f68d06185a67541243ca8683a46dac97678c49f8a0b44120d58d305c1c8ea", size = 7900 },
+]
+
+[[package]]
+name = "requests"
+version = "2.32.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "certifi" },
+ { name = "charset-normalizer" },
+ { name = "idna" },
+ { name = "urllib3" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 },
+]
+
+[[package]]
+name = "restrictedpython"
+version = "8.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/76/f3/3cfd684abf456f536a842e4fabe1ca360a8e94d1fc329f261c34c1d98825/restrictedpython-8.0.tar.gz", hash = "sha256:3af2312bc67e5fced887fb85b006c89861da72488128b155beea81eb6a0a9b24", size = 448747 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/31/b33804f873742ab20c8ed82a75652bf60a6205116dfec8bb092a6ebef084/RestrictedPython-8.0-py3-none-any.whl", hash = "sha256:ed3d894efd7d6cac0a5f13f75583b8458378d400d7dd4c083b59233eba85fe69", size = 27238 },
+]
+
+[[package]]
+name = "robotframework"
+version = "6.0.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/8e/08/018fa8662f17ae912debcb939f8279fc40c4cf0bf172fdd1875532997e41/robotframework-6.0.2.zip", hash = "sha256:6a9c06deb220099990f190c6e4e772675f625e4d5d84640fca6f0ad46ff538d0", size = 689068 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/72/26/5a391509c611bda444e73228a89694accac1f1e6e84c11964ba163b81b1a/robotframework-6.0.2-py3-none-any.whl", hash = "sha256:634cd6f9fdc21142eadd9aacdddbfe7d3e2a757532b71d866dbb404cd0e66dac", size = 658729 },
+]
+
+[[package]]
+name = "robotframework-assertion-engine"
+version = "3.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "robotframework" },
+ { name = "robotframework-pythonlibcore" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/82/6a/64caaaff181a6f56847124a98e029bd91e3479c56f2db2803e3f5e19a8d8/robotframework_assertion_engine-3.0.3.tar.gz", hash = "sha256:1c608d4c69d96520986a1ddc6def0fc7f7e849520f1e6882a633b51dbb98fd88", size = 11901 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/51/5d/b160d9a55db18f9847e0cc680012dfab03e9efcebae0a09280d57ae8a6ee/robotframework_assertion_engine-3.0.3-py3-none-any.whl", hash = "sha256:3cd8962744ea4f307feadd596266c1d563e87b586ed61803c9445295ab15a0cd", size = 12944 },
+]
+
+[[package]]
+name = "robotframework-browser"
+version = "19.3.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "click" },
+ { name = "grpcio" },
+ { name = "grpcio-tools" },
+ { name = "overrides" },
+ { name = "protobuf" },
+ { name = "robotframework" },
+ { name = "robotframework-assertion-engine" },
+ { name = "robotframework-pythonlibcore" },
+ { name = "seedir" },
+ { name = "wrapt" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/44/41/c76cfe7b7ea1d4e28042f52a7a27fd0b026a50dadb932a288300587d59c9/robotframework_browser-19.3.1.tar.gz", hash = "sha256:79a6427af0c77752bfd2fa49e40ae88c7ff7e48c4639f42604d9ba72b9f9e964", size = 504186 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9f/48/ea82a21793355b30bb6a529e84af736c882190366f4e93d0088a4327f116/robotframework_browser-19.3.1-py3-none-any.whl", hash = "sha256:ab797e9068d98dafd2d338a599148b9e9630d0d05fef6367022bb5d255d5f2c0", size = 518115 },
+]
+
+[[package]]
+name = "robotframework-debuglibrary"
+version = "2.5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "prompt-toolkit" },
+ { name = "robotframework" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fd/b3/c5fa5fb8e0786efacc30a16f9ae62d90d838516c2dea08ad2733d679bd66/robotframework-debuglibrary-2.5.0.tar.gz", hash = "sha256:c8e135c7561721d36210d6f59a09b7538064367e82d8a3be67cb87088cf9cba7", size = 18407 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/73/32/94f7b214f9bbbbf4d461e44a58533a7bf144477df43d3d741fe57f5a5143/robotframework_debuglibrary-2.5.0-py3-none-any.whl", hash = "sha256:a2bfb2636ead7be440c224317891b4b406a9a71d84b26924031ccf3791a00b96", size = 19245 },
+]
+
+[[package]]
+name = "robotframework-pythonlibcore"
+version = "4.4.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/71/89/5dc8c8186c897ee4b7d0b2631ebc90e679e8c8f04ea85505f96ad38aad64/robotframework-pythonlibcore-4.4.1.tar.gz", hash = "sha256:2d695b2ea906f5815179643e29182466675e682d82c5fa9d1009edfae2f84b16", size = 12835 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ac/64/47d8403c7c0af89b46461640a2f67e49a5778062b8dd6eb3e128aa3c50cc/robotframework_pythonlibcore-4.4.1-py2.py3-none-any.whl", hash = "sha256:e0517129522aaa039eb2a28fd3d9720b7a0be0b90d0cbcb153a6c8016bb9e973", size = 12452 },
+]
+
+[[package]]
+name = "robotframework-selenium2library"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "robotframework-seleniumlibrary" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c4/7d/3c07081e7f0f1844aa21fd239a0139db4da5a8dc219d1e81cb004ba1f4e2/robotframework-selenium2library-3.0.0.tar.gz", hash = "sha256:2a8e942b0788b16ded253039008b34d2b46199283461b294f0f41a579c70fda7", size = 71087 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1c/f1/612f9aa29f33b25a1034749dde67dfbf6de9b297709d06df71f9bfabfc81/robotframework_selenium2library-3.0.0-py2.py3-none-any.whl", hash = "sha256:1826b1ce8ccac76f14c4812e2d6df79f52ecda8a3c59c427eea45548c2e22cb1", size = 6235 },
+]
+
+[[package]]
+name = "robotframework-seleniumlibrary"
+version = "6.1.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "robotframework" },
+ { name = "robotframework-pythonlibcore" },
+ { name = "selenium" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/75/66/6a704118c5c8d3bd6b671364c73cee4ad8045188c321c8e7abdd468bc4e2/robotframework-seleniumlibrary-6.1.3.tar.gz", hash = "sha256:2cbe8954c7201c510a1d197381aace6f3a9a8a4b0abea3fa13f4d947fe47ea49", size = 163774 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f1/d5/1754ffca0a1c054c1101b531e8ecc0263b20c7bd9c9763adeea6b87d0e4c/robotframework_seleniumlibrary-6.1.3-py2.py3-none-any.whl", hash = "sha256:078649982b535be21a44def15da609d6b9518e47bdfb71e9c2a8e0ab0c7f5556", size = 95348 },
+]
+
+[[package]]
+name = "robotframework-seleniumtestability"
+version = "2.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "furl" },
+ { name = "robotframework-seleniumlibrary" },
+ { name = "wrapt" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ce/63/1e1c64311859c4ea6817acf8bf1f6635d01517d2e79e4496457e961bc921/robotframework-seleniumtestability-2.1.0.tar.gz", hash = "sha256:2398489992a8b6cbfb5b6da38b76178c03826eff26a0e1d20f473f284efcc8ae", size = 228079 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/13/fd/2c5006a4e19746ecaa95e5ef1c7c7a83971f06c366379bad47c311823dce/robotframework_seleniumtestability-2.1.0-py3-none-any.whl", hash = "sha256:b312783f2e26c39c5002ea6db561088a1c8cc551af1dd27b37cb7c04566bbc5c", size = 23793 },
+]
+
+[[package]]
+name = "robotsuite"
+version = "2.3.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lxml" },
+ { name = "robotframework" },
+ { name = "setuptools" },
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9f/a8/893b6615c3d72583394731166217184334624cd09c78516d7a56f08951da/robotsuite-2.3.2.tar.gz", hash = "sha256:b0f98ea11e4afa031fc8f93640c6e20cd9963d172a2abb33e993c100a47fdd76", size = 30546 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a8/8a/7ff8c565c636e41a3a21d260910b2ae01d11e259bdffd6996c7fcb1f5af0/robotsuite-2.3.2-py2.py3-none-any.whl", hash = "sha256:c3545fc0e19e1c71cf49a4aef77d0e648ca2544c5775fbe4cd704560d7246427", size = 19035 },
+]
+
+[[package]]
+name = "roman"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/85/49/b01cf3c88006005613234cfc78b2e371adc3b55fe125641679bca46963f9/roman-5.0.tar.gz", hash = "sha256:cb35293c1c4046105fd899194f4f2985f78c955a8b05937f7ab93f3be1660697", size = 7664 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a2/c0/34a98c0bdf3e5846ed5fea15c0a20fae0ad95478013f7582e807da0f7cb5/roman-5.0-py3-none-any.whl", hash = "sha256:6e1246c0aa9338aa5603e8bf4960f76d5047be1878d8d1ceb0d2c452b5b890e2", size = 5519 },
+]
+
+[[package]]
+name = "rpds-py"
+version = "0.22.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/01/80/cce854d0921ff2f0a9fa831ba3ad3c65cee3a46711addf39a2af52df2cfd/rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", size = 26771 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/75/47/3383ee3bd787a2a5e65a9b9edc37ccf8505c0a00170e3a5e6ea5fbcd97f7/rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", size = 352334 },
+ { url = "https://files.pythonhosted.org/packages/40/14/aa6400fa8158b90a5a250a77f2077c0d0cd8a76fce31d9f2b289f04c6dec/rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", size = 342111 },
+ { url = "https://files.pythonhosted.org/packages/7d/06/395a13bfaa8a28b302fb433fb285a67ce0ea2004959a027aea8f9c52bad4/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", size = 384286 },
+ { url = "https://files.pythonhosted.org/packages/43/52/d8eeaffab047e6b7b7ef7f00d5ead074a07973968ffa2d5820fa131d7852/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e", size = 391739 },
+ { url = "https://files.pythonhosted.org/packages/83/31/52dc4bde85c60b63719610ed6f6d61877effdb5113a72007679b786377b8/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", size = 427306 },
+ { url = "https://files.pythonhosted.org/packages/70/d5/1bab8e389c2261dba1764e9e793ed6830a63f830fdbec581a242c7c46bda/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", size = 442717 },
+ { url = "https://files.pythonhosted.org/packages/82/a1/a45f3e30835b553379b3a56ea6c4eb622cf11e72008229af840e4596a8ea/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", size = 385721 },
+ { url = "https://files.pythonhosted.org/packages/a6/27/780c942de3120bdd4d0e69583f9c96e179dfff082f6ecbb46b8d6488841f/rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", size = 415824 },
+ { url = "https://files.pythonhosted.org/packages/94/0b/aa0542ca88ad20ea719b06520f925bae348ea5c1fdf201b7e7202d20871d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", size = 561227 },
+ { url = "https://files.pythonhosted.org/packages/0d/92/3ed77d215f82c8f844d7f98929d56cc321bb0bcfaf8f166559b8ec56e5f1/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", size = 587424 },
+ { url = "https://files.pythonhosted.org/packages/09/42/cacaeb047a22cab6241f107644f230e2935d4efecf6488859a7dd82fc47d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", size = 555953 },
+ { url = "https://files.pythonhosted.org/packages/e6/52/c921dc6d5f5d45b212a456c1f5b17df1a471127e8037eb0972379e39dff4/rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", size = 221339 },
+ { url = "https://files.pythonhosted.org/packages/f2/c7/f82b5be1e8456600395366f86104d1bd8d0faed3802ad511ef6d60c30d98/rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", size = 235786 },
+ { url = "https://files.pythonhosted.org/packages/d0/bf/36d5cc1f2c609ae6e8bf0fc35949355ca9d8790eceb66e6385680c951e60/rpds_py-0.22.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84", size = 351657 },
+ { url = "https://files.pythonhosted.org/packages/24/2a/f1e0fa124e300c26ea9382e59b2d582cba71cedd340f32d1447f4f29fa4e/rpds_py-0.22.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25", size = 341829 },
+ { url = "https://files.pythonhosted.org/packages/cf/c2/0da1231dd16953845bed60d1a586fcd6b15ceaeb965f4d35cdc71f70f606/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4", size = 384220 },
+ { url = "https://files.pythonhosted.org/packages/c7/73/a4407f4e3a00a9d4b68c532bf2d873d6b562854a8eaff8faa6133b3588ec/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5", size = 391009 },
+ { url = "https://files.pythonhosted.org/packages/a9/c3/04b7353477ab360fe2563f5f0b176d2105982f97cd9ae80a9c5a18f1ae0f/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc", size = 426989 },
+ { url = "https://files.pythonhosted.org/packages/8d/e6/e4b85b722bcf11398e17d59c0f6049d19cd606d35363221951e6d625fcb0/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b", size = 441544 },
+ { url = "https://files.pythonhosted.org/packages/27/fc/403e65e56f65fff25f2973216974976d3f0a5c3f30e53758589b6dc9b79b/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518", size = 385179 },
+ { url = "https://files.pythonhosted.org/packages/57/9b/2be9ff9700d664d51fd96b33d6595791c496d2778cb0b2a634f048437a55/rpds_py-0.22.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd", size = 415103 },
+ { url = "https://files.pythonhosted.org/packages/bb/a5/03c2ad8ca10994fcf22dd2150dd1d653bc974fa82d9a590494c84c10c641/rpds_py-0.22.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2", size = 560916 },
+ { url = "https://files.pythonhosted.org/packages/ba/2e/be4fdfc8b5b576e588782b56978c5b702c5a2307024120d8aeec1ab818f0/rpds_py-0.22.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16", size = 587062 },
+ { url = "https://files.pythonhosted.org/packages/67/e0/2034c221937709bf9c542603d25ad43a68b4b0a9a0c0b06a742f2756eb66/rpds_py-0.22.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f", size = 555734 },
+ { url = "https://files.pythonhosted.org/packages/ea/ce/240bae07b5401a22482b58e18cfbabaa392409b2797da60223cca10d7367/rpds_py-0.22.3-cp313-cp313-win32.whl", hash = "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de", size = 220663 },
+ { url = "https://files.pythonhosted.org/packages/cb/f0/d330d08f51126330467edae2fa4efa5cec8923c87551a79299380fdea30d/rpds_py-0.22.3-cp313-cp313-win_amd64.whl", hash = "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9", size = 235503 },
+ { url = "https://files.pythonhosted.org/packages/f7/c4/dbe1cc03df013bf2feb5ad00615038050e7859f381e96fb5b7b4572cd814/rpds_py-0.22.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b", size = 347698 },
+ { url = "https://files.pythonhosted.org/packages/a4/3a/684f66dd6b0f37499cad24cd1c0e523541fd768576fa5ce2d0a8799c3cba/rpds_py-0.22.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b", size = 337330 },
+ { url = "https://files.pythonhosted.org/packages/82/eb/e022c08c2ce2e8f7683baa313476492c0e2c1ca97227fe8a75d9f0181e95/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1", size = 380022 },
+ { url = "https://files.pythonhosted.org/packages/e4/21/5a80e653e4c86aeb28eb4fea4add1f72e1787a3299687a9187105c3ee966/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83", size = 390754 },
+ { url = "https://files.pythonhosted.org/packages/37/a4/d320a04ae90f72d080b3d74597074e62be0a8ecad7d7321312dfe2dc5a6a/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd", size = 423840 },
+ { url = "https://files.pythonhosted.org/packages/87/70/674dc47d93db30a6624279284e5631be4c3a12a0340e8e4f349153546728/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1", size = 438970 },
+ { url = "https://files.pythonhosted.org/packages/3f/64/9500f4d66601d55cadd21e90784cfd5d5f4560e129d72e4339823129171c/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3", size = 383146 },
+ { url = "https://files.pythonhosted.org/packages/4d/45/630327addb1d17173adcf4af01336fd0ee030c04798027dfcb50106001e0/rpds_py-0.22.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130", size = 408294 },
+ { url = "https://files.pythonhosted.org/packages/5f/ef/8efb3373cee54ea9d9980b772e5690a0c9e9214045a4e7fa35046e399fee/rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c", size = 556345 },
+ { url = "https://files.pythonhosted.org/packages/54/01/151d3b9ef4925fc8f15bfb131086c12ec3c3d6dd4a4f7589c335bf8e85ba/rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b", size = 582292 },
+ { url = "https://files.pythonhosted.org/packages/30/89/35fc7a6cdf3477d441c7aca5e9bbf5a14e0f25152aed7f63f4e0b141045d/rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333", size = 553855 },
+ { url = "https://files.pythonhosted.org/packages/8f/e0/830c02b2457c4bd20a8c5bb394d31d81f57fbefce2dbdd2e31feff4f7003/rpds_py-0.22.3-cp313-cp313t-win32.whl", hash = "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730", size = 219100 },
+ { url = "https://files.pythonhosted.org/packages/f8/30/7ac943f69855c2db77407ae363484b915d861702dbba1aa82d68d57f42be/rpds_py-0.22.3-cp313-cp313t-win_amd64.whl", hash = "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf", size = 233794 },
+]
+
+[[package]]
+name = "seedir"
+version = "0.5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "natsort" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/46/84/530a5e4abbc0bb195f388b040268e9c81a52f7127cab41a7dbb448087c54/seedir-0.5.0.tar.gz", hash = "sha256:e6f80f9535b57413100f04933fd269f856aca1d067bccadf3ea3ca98a2fc6fc5", size = 3105170 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e5/b4/0f5c167f3ab597c693f4c98d3bcaad940cc8a1529ce4029d8e988d0f52da/seedir-0.5.0-py3-none-any.whl", hash = "sha256:fd30221e9a6d92701b6f82cc09285d0c88b16b63a728652c34b3a0bd7363ae68", size = 112992 },
+]
+
+[[package]]
+name = "selenium"
+version = "4.9.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "certifi" },
+ { name = "trio" },
+ { name = "trio-websocket" },
+ { name = "urllib3", extra = ["socks"] },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fd/e2/0e5bee6762a7bf7852b47a79c5b12f9e526e6962958dbb9719fa490ba24c/selenium-4.9.1.tar.gz", hash = "sha256:3444f4376321530c36ce8355b6b357d8cf4a7d588ce5cf772183465930bbed0e", size = 6341857 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b4/5c/803b797ba26bcd741c3b460b9a2ac663c04f21e8e4e425d26c1c842ca438/selenium-4.9.1-py3-none-any.whl", hash = "sha256:82aedaa85d55bc861f4c89ff9609e82f6c958e2e1e3da3ffcc36703f21d3ee16", size = 6551247 },
+]
+
+[[package]]
+name = "setuptools"
+version = "75.8.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d1/53/43d99d7687e8cdef5ab5f9ec5eaf2c0423c2b35133a2b7e7bc276fc32b21/setuptools-75.8.2.tar.gz", hash = "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2", size = 1344083 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a9/38/7d7362e031bd6dc121e5081d8cb6aa6f6fedf2b67bf889962134c6da4705/setuptools-75.8.2-py3-none-any.whl", hash = "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f", size = 1229385 },
+]
+
+[[package]]
+name = "sgmllib3k"
+version = "1.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/9e/bd/3704a8c3e0942d711c1299ebf7b9091930adae6675d7c8f476a7ce48653c/sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9", size = 5750 }
+
+[[package]]
+name = "simplejson"
+version = "3.19.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/3d/29/085111f19717f865eceaf0d4397bf3e76b08d60428b076b64e2a1903706d/simplejson-3.19.3.tar.gz", hash = "sha256:8e086896c36210ab6050f2f9f095a5f1e03c83fa0e7f296d6cba425411364680", size = 85237 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/20/15/513fea93fafbdd4993eacfcb762965b2ff3d29e618c029e2956174d68c4b/simplejson-3.19.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:66a0399e21c2112acacfebf3d832ebe2884f823b1c7e6d1363f2944f1db31a99", size = 92921 },
+ { url = "https://files.pythonhosted.org/packages/a4/4f/998a907ae1a6c104dc0ee48aa248c2478490152808d34d8e07af57f396c3/simplejson-3.19.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6ef9383c5e05f445be60f1735c1816163c874c0b1ede8bb4390aff2ced34f333", size = 75311 },
+ { url = "https://files.pythonhosted.org/packages/db/44/acd6122201e927451869d45952b9ab1d3025cdb5e61548d286d08fbccc08/simplejson-3.19.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:42e5acf80d4d971238d4df97811286a044d720693092b20a56d5e56b7dcc5d09", size = 74964 },
+ { url = "https://files.pythonhosted.org/packages/27/ca/d0a1e8f16e1bbdc0b8c6d88166f45f565ed7285f53928cfef3b6ce78f14d/simplejson-3.19.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0b0efc7279d768db7c74d3d07f0b5c81280d16ae3fb14e9081dc903e8360771", size = 150106 },
+ { url = "https://files.pythonhosted.org/packages/63/59/0554b78cf26c98e2b9cae3f44723bd72c2394e2afec1a14eedc6211f7187/simplejson-3.19.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0552eb06e7234da892e1d02365cd2b7b2b1f8233aa5aabdb2981587b7cc92ea0", size = 158347 },
+ { url = "https://files.pythonhosted.org/packages/b2/fe/9f30890352e431e8508cc569912d3322147d3e7e4f321e48c0adfcb4c97d/simplejson-3.19.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf6a3b9a7d7191471b464fe38f684df10eb491ec9ea454003edb45a011ab187", size = 148456 },
+ { url = "https://files.pythonhosted.org/packages/37/e3/663a09542ee021d4131162f7a164cb2e7f04ef48433a67591738afbf12ea/simplejson-3.19.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7017329ca8d4dca94ad5e59f496e5fc77630aecfc39df381ffc1d37fb6b25832", size = 152190 },
+ { url = "https://files.pythonhosted.org/packages/31/20/4e0c4d35e10ff6465003bec304316d822a559a1c38c66ef6892ca199c207/simplejson-3.19.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:67a20641afebf4cfbcff50061f07daad1eace6e7b31d7622b6fa2c40d43900ba", size = 149846 },
+ { url = "https://files.pythonhosted.org/packages/08/7a/46e2e072cac3987cbb05946f25167f0ad2fe536748e7405953fd6661a486/simplejson-3.19.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd6a7dabcc4c32daf601bc45e01b79175dde4b52548becea4f9545b0a4428169", size = 151714 },
+ { url = "https://files.pythonhosted.org/packages/7f/7d/dbeeac10eb61d5d8858d0bb51121a21050d281dc83af4c557f86da28746c/simplejson-3.19.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:08f9b443a94e72dd02c87098c96886d35790e79e46b24e67accafbf13b73d43b", size = 158777 },
+ { url = "https://files.pythonhosted.org/packages/fc/8f/a98bdbb799c6a4a884b5823db31785a96ba895b4b0f4d8ac345d6fe98bbf/simplejson-3.19.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fa97278ae6614346b5ca41a45a911f37a3261b57dbe4a00602048652c862c28b", size = 154230 },
+ { url = "https://files.pythonhosted.org/packages/b1/db/852eebceb85f969ae40e06babed1a93d3bacb536f187d7a80ff5823a5979/simplejson-3.19.3-cp312-cp312-win32.whl", hash = "sha256:ef28c3b328d29b5e2756903aed888960bc5df39b4c2eab157ae212f70ed5bf74", size = 74002 },
+ { url = "https://files.pythonhosted.org/packages/fe/68/9f0e5df0651cb79ef83cba1378765a00ee8038e6201cc82b8e7178a7778e/simplejson-3.19.3-cp312-cp312-win_amd64.whl", hash = "sha256:1e662336db50ad665777e6548b5076329a94a0c3d4a0472971c588b3ef27de3a", size = 75596 },
+ { url = "https://files.pythonhosted.org/packages/93/3a/5896821ed543899fcb9c4256c7e71bb110048047349a00f42bc8b8fb379f/simplejson-3.19.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0959e6cb62e3994b5a40e31047ff97ef5c4138875fae31659bead691bed55896", size = 92931 },
+ { url = "https://files.pythonhosted.org/packages/39/15/5d33d269440912ee40d856db0c8be2b91aba7a219690ab01f86cb0edd590/simplejson-3.19.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a7bfad839c624e139a4863007233a3f194e7c51551081f9789cba52e4da5167", size = 75318 },
+ { url = "https://files.pythonhosted.org/packages/2a/8d/2e7483a2bf7ec53acf7e012bafbda79d7b34f90471dda8e424544a59d484/simplejson-3.19.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afab2f7f2486a866ff04d6d905e9386ca6a231379181a3838abce1f32fbdcc37", size = 74971 },
+ { url = "https://files.pythonhosted.org/packages/4d/9d/9bdf34437c8834a7cf7246f85e9d5122e30579f512c10a0c2560e994294f/simplejson-3.19.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00313681015ac498e1736b304446ee6d1c72c5b287cd196996dad84369998f7", size = 150112 },
+ { url = "https://files.pythonhosted.org/packages/a7/e2/1f2ae2d89eaf85f6163c82150180aae5eaa18085cfaf892f8a57d4c51cbd/simplejson-3.19.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d936ae682d5b878af9d9eb4d8bb1fdd5e41275c8eb59ceddb0aeed857bb264a2", size = 158354 },
+ { url = "https://files.pythonhosted.org/packages/60/83/26f610adf234c8492b3f30501e12f2271e67790f946c6898fe0c58aefe99/simplejson-3.19.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c6657485393f2e9b8177c77a7634f13ebe70d5e6de150aae1677d91516ce6b", size = 148455 },
+ { url = "https://files.pythonhosted.org/packages/b5/4b/109af50006af77133653c55b5b91b4bd2d579ff8254ce11216c0b75f911b/simplejson-3.19.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a6a750d3c7461b1c47cfc6bba8d9e57a455e7c5f80057d2a82f738040dd1129", size = 152191 },
+ { url = "https://files.pythonhosted.org/packages/75/dc/108872a8825cbd99ae6f4334e0490ff1580367baf12198bcaf988f6820ba/simplejson-3.19.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ea7a4a998c87c5674a27089e022110a1a08a7753f21af3baf09efe9915c23c3c", size = 149954 },
+ { url = "https://files.pythonhosted.org/packages/eb/be/deec1d947a5d0472276ab4a4d1a9378dc5ee27f3dc9e54d4f62ffbad7a08/simplejson-3.19.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6300680d83a399be2b8f3b0ef7ef90b35d2a29fe6e9c21438097e0938bbc1564", size = 151812 },
+ { url = "https://files.pythonhosted.org/packages/e9/58/4ee130702d36b1551ef66e7587eefe56651f3669255bf748cd71691e2434/simplejson-3.19.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ab69f811a660c362651ae395eba8ce84f84c944cea0df5718ea0ba9d1e4e7252", size = 158880 },
+ { url = "https://files.pythonhosted.org/packages/0f/e1/59cc6a371b60f89e3498d9f4c8109f6b7359094d453f5fe80b2677b777b0/simplejson-3.19.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:256e09d0f94d9c3d177d9e95fd27a68c875a4baa2046633df387b86b652f5747", size = 154344 },
+ { url = "https://files.pythonhosted.org/packages/79/45/1b36044670016f5cb25ebd92497427d2d1711ecb454d00f71eb9a00b77cc/simplejson-3.19.3-cp313-cp313-win32.whl", hash = "sha256:2c78293470313aefa9cfc5e3f75ca0635721fb016fb1121c1c5b0cb8cc74712a", size = 74002 },
+ { url = "https://files.pythonhosted.org/packages/e2/58/b06226e6b0612f2b1fa13d5273551da259f894566b1eef32249ddfdcce44/simplejson-3.19.3-cp313-cp313-win_amd64.whl", hash = "sha256:3bbcdc438dc1683b35f7a8dc100960c721f922f9ede8127f63bed7dfded4c64c", size = 75599 },
+ { url = "https://files.pythonhosted.org/packages/0d/e7/f9fafbd4f39793a20cc52e77bbd766f7384312526d402c382928dc7667f6/simplejson-3.19.3-py3-none-any.whl", hash = "sha256:49cc4c7b940d43bd12bf87ec63f28cbc4964fc4e12c031cc8cd01650f43eb94e", size = 57004 },
+]
+
+[[package]]
+name = "six"
+version = "1.17.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
+]
+
+[[package]]
+name = "sniffio"
+version = "1.3.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
+]
+
+[[package]]
+name = "sortedcontainers"
+version = "2.4.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 },
+]
+
+[[package]]
+name = "souper"
+version = "1.1.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "node-ext-zodb" },
+ { name = "repoze-catalog" },
+ { name = "setuptools" },
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fe/14/8d08137567531fd283569079d31f38d0e3d9880f3c3855ef71d7a5f4b152/souper-1.1.2.tar.gz", hash = "sha256:38a0fcf8e1d1e830895483e7d3d91a03a4c465c3855051e805d518f53aa81c9d", size = 25626 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/21/03/22dba11501592d08d43b83d3c81fb09bad776dacb9dca2ec439db41f1b71/souper-1.1.2-py3-none-any.whl", hash = "sha256:07f8bcfc858c5d764f0fde8f62636280916c08309cf872f380417e89d9d7396e", size = 11466 },
+]
+
+[[package]]
+name = "souper-plone"
+version = "1.3.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "products-cmfplone" },
+ { name = "setuptools" },
+ { name = "souper" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/dd/ef/3b8cf7f86581e2ba5610e4d618a1ea1e95c6ef271934985399378fa24ed2/souper.plone-1.3.1.tar.gz", hash = "sha256:1490b602d22d2dc7992fa38c064ab49846d8a045a050117c564264a6277d93b1", size = 17071 }
+
+[[package]]
+name = "soupsieve"
+version = "2.6"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 },
+]
+
+[[package]]
+name = "transaction"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ef/fe/37ef03bdecfb078053421dc7ba2ed974c57e22548f2bd235a9ec5cd8efbb/transaction-5.0.tar.gz", hash = "sha256:106e7bd782bcc0cb5119fc9225b0c9a71dfc53adb938be905223adaef22b1174", size = 87121 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ae/2a/b531f79737312fedf0af878e38bfd42be3a31a7cc74bc89c5f22173ce2ad/transaction-5.0-py3-none-any.whl", hash = "sha256:b4c0b2d49a042d86235fa76531c3356b66d7635bb0e9f29ba2512915fc7b7a42", size = 46295 },
+]
+
+[[package]]
+name = "trio"
+version = "0.27.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+ { name = "cffi", marker = "implementation_name != 'pypy' and os_name == 'nt'" },
+ { name = "idna" },
+ { name = "outcome" },
+ { name = "sniffio" },
+ { name = "sortedcontainers" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/17/d1/a83dee5be404da7afe5a71783a33b8907bacb935a6dc8c69ab785e4a3eed/trio-0.27.0.tar.gz", hash = "sha256:1dcc95ab1726b2da054afea8fd761af74bad79bd52381b84eae408e983c76831", size = 568064 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3c/83/ec3196c360afffbc5b342ead48d1eb7393dd74fa70bca75d33905a86f211/trio-0.27.0-py3-none-any.whl", hash = "sha256:68eabbcf8f457d925df62da780eff15ff5dc68fd6b367e2dde59f7aaf2a0b884", size = 481734 },
+]
+
+[[package]]
+name = "trio-websocket"
+version = "0.11.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "trio" },
+ { name = "wsproto" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/dd/36/abad2385853077424a11b818d9fd8350d249d9e31d583cb9c11cd4c85eda/trio-websocket-0.11.1.tar.gz", hash = "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f", size = 26511 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/48/be/a9ae5f50cad5b6f85bd2574c2c923730098530096e170c1ce7452394d7aa/trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638", size = 17408 },
+]
+
+[[package]]
+name = "trove-classifiers"
+version = "2025.2.18.16"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/13/8e/15ba2980e2704edecc53d15506a5bfa6efb3b1cadc5e4df7dc277bc199f8/trove_classifiers-2025.2.18.16.tar.gz", hash = "sha256:b1ee2e1668589217d4edf506743e28b1834da128f8a122bad522c02d837006e1", size = 16271 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e1/67/038a8c7f60ffd6037374649826dbaa221e4b17755016b71a581162a15ce1/trove_classifiers-2025.2.18.16-py3-none-any.whl", hash = "sha256:7f6dfae899f23f04b73bc09e0754d9219a6fc4d6cca6acd62f1850a87ea92262", size = 13616 },
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
+]
+
+[[package]]
+name = "tzdata"
+version = "2025.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 },
+]
+
+[[package]]
+name = "unidecode"
+version = "1.3.8"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f7/89/19151076a006b9ac0dd37b1354e031f5297891ee507eb624755e58e10d3e/Unidecode-1.3.8.tar.gz", hash = "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4", size = 192701 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/84/b7/6ec57841fb67c98f52fc8e4a2d96df60059637cba077edc569a302a8ffc7/Unidecode-1.3.8-py3-none-any.whl", hash = "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39", size = 235494 },
+]
+
+[[package]]
+name = "urllib3"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 },
+]
+
+[package.optional-dependencies]
+socks = [
+ { name = "pysocks" },
+]
+
+[[package]]
+name = "waitress"
+version = "3.0.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/bf/cb/04ddb054f45faa306a230769e868c28b8065ea196891f09004ebace5b184/waitress-3.0.2.tar.gz", hash = "sha256:682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f", size = 179901 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8d/57/a27182528c90ef38d82b636a11f606b0cbb0e17588ed205435f8affe3368/waitress-3.0.2-py3-none-any.whl", hash = "sha256:c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e", size = 56232 },
+]
+
+[[package]]
+name = "wcwidth"
+version = "0.2.13"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 },
+]
+
+[[package]]
+name = "webob"
+version = "1.8.9"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "legacy-cgi", marker = "python_full_version >= '3.13'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/85/0b/1732085540b01f65e4e7999e15864fe14cd18b12a95731a43fd6fd11b26a/webob-1.8.9.tar.gz", hash = "sha256:ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589", size = 279775 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/50/bd/c336448be43d40be28e71f2e0f3caf7ccb28e2755c58f4c02c065bfe3e8e/WebOb-1.8.9-py2.py3-none-any.whl", hash = "sha256:45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9", size = 115364 },
+]
+
+[[package]]
+name = "webresource"
+version = "1.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/0d/d3/7ffc8b9bd114ea17162528e75d8e7a9624b928070375b349e68b500aa515/webresource-1.2.tar.gz", hash = "sha256:361ef36b25b85876a389b755bb4a0d162493b3b0dd3e1f8949284a6fe0341266", size = 19817 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/95/16/221f117174955e12995270ca64df1a5e29630ae2e6d4e52e363b29532963/webresource-1.2-py3-none-any.whl", hash = "sha256:448ed3dbff81a7ef8b8ade827a33984520dfe65727e508b3f8ce269db98f8b06", size = 14732 },
+]
+
+[[package]]
+name = "webtest"
+version = "3.0.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "beautifulsoup4" },
+ { name = "waitress" },
+ { name = "webob" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/48/aa/cc6c35e99a7f21fe53a5210446c6615e57f561cb0288072f52b1d78279cd/webtest-3.0.3.tar.gz", hash = "sha256:b635f6fe6584bc9737496b687155e9373f3d01bcb1b46169007da0f7ba6238f9", size = 79391 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/17/85/744fc36fe0a3fb9cd219c1d92c6ff6fa46b9e5abbf70260b46b505043f83/WebTest-3.0.3-py3-none-any.whl", hash = "sha256:25a2f3b1ad273655ed22fdb4f9eff62d02f22d9d5ffeb0b58627759b1f62edff", size = 32148 },
+]
+
+[[package]]
+name = "wheel"
+version = "0.45.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", size = 107545 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494 },
+]
+
+[[package]]
+name = "wrapt"
+version = "1.17.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/24/a1/fc03dca9b0432725c2e8cdbf91a349d2194cf03d8523c124faebe581de09/wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801", size = 55542 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/85/82/518605474beafff11f1a34759f6410ab429abff9f7881858a447e0d20712/wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569", size = 38904 },
+ { url = "https://files.pythonhosted.org/packages/80/6c/17c3b2fed28edfd96d8417c865ef0b4c955dc52c4e375d86f459f14340f1/wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504", size = 88622 },
+ { url = "https://files.pythonhosted.org/packages/4a/11/60ecdf3b0fd3dca18978d89acb5d095a05f23299216e925fcd2717c81d93/wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451", size = 80920 },
+ { url = "https://files.pythonhosted.org/packages/d2/50/dbef1a651578a3520d4534c1e434989e3620380c1ad97e309576b47f0ada/wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1", size = 89170 },
+ { url = "https://files.pythonhosted.org/packages/44/a2/78c5956bf39955288c9e0dd62e807b308c3aa15a0f611fbff52aa8d6b5ea/wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106", size = 86748 },
+ { url = "https://files.pythonhosted.org/packages/99/49/2ee413c78fc0bdfebe5bee590bf3becdc1fab0096a7a9c3b5c9666b2415f/wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada", size = 79734 },
+ { url = "https://files.pythonhosted.org/packages/c0/8c/4221b7b270e36be90f0930fe15a4755a6ea24093f90b510166e9ed7861ea/wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4", size = 87552 },
+ { url = "https://files.pythonhosted.org/packages/4c/6b/1aaccf3efe58eb95e10ce8e77c8909b7a6b0da93449a92c4e6d6d10b3a3d/wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635", size = 36647 },
+ { url = "https://files.pythonhosted.org/packages/b3/4f/243f88ac49df005b9129194c6511b3642818b3e6271ddea47a15e2ee4934/wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7", size = 38830 },
+ { url = "https://files.pythonhosted.org/packages/67/9c/38294e1bb92b055222d1b8b6591604ca4468b77b1250f59c15256437644f/wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181", size = 38904 },
+ { url = "https://files.pythonhosted.org/packages/78/b6/76597fb362cbf8913a481d41b14b049a8813cd402a5d2f84e57957c813ae/wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393", size = 88608 },
+ { url = "https://files.pythonhosted.org/packages/bc/69/b500884e45b3881926b5f69188dc542fb5880019d15c8a0df1ab1dfda1f7/wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4", size = 80879 },
+ { url = "https://files.pythonhosted.org/packages/52/31/f4cc58afe29eab8a50ac5969963010c8b60987e719c478a5024bce39bc42/wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b", size = 89119 },
+ { url = "https://files.pythonhosted.org/packages/aa/9c/05ab6bf75dbae7a9d34975fb6ee577e086c1c26cde3b6cf6051726d33c7c/wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721", size = 86778 },
+ { url = "https://files.pythonhosted.org/packages/0e/6c/4b8d42e3db355603d35fe5c9db79c28f2472a6fd1ccf4dc25ae46739672a/wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90", size = 79793 },
+ { url = "https://files.pythonhosted.org/packages/69/23/90e3a2ee210c0843b2c2a49b3b97ffcf9cad1387cb18cbeef9218631ed5a/wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a", size = 87606 },
+ { url = "https://files.pythonhosted.org/packages/5f/06/3683126491ca787d8d71d8d340e775d40767c5efedb35039d987203393b7/wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045", size = 36651 },
+ { url = "https://files.pythonhosted.org/packages/f1/bc/3bf6d2ca0d2c030d324ef9272bea0a8fdaff68f3d1fa7be7a61da88e51f7/wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838", size = 38835 },
+ { url = "https://files.pythonhosted.org/packages/ce/b5/251165c232d87197a81cd362eeb5104d661a2dd3aa1f0b33e4bf61dda8b8/wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b", size = 40146 },
+ { url = "https://files.pythonhosted.org/packages/89/33/1e1bdd3e866eeb73d8c4755db1ceb8a80d5bd51ee4648b3f2247adec4e67/wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379", size = 113444 },
+ { url = "https://files.pythonhosted.org/packages/9f/7c/94f53b065a43f5dc1fbdd8b80fd8f41284315b543805c956619c0b8d92f0/wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d", size = 101246 },
+ { url = "https://files.pythonhosted.org/packages/62/5d/640360baac6ea6018ed5e34e6e80e33cfbae2aefde24f117587cd5efd4b7/wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f", size = 109320 },
+ { url = "https://files.pythonhosted.org/packages/e3/cf/6c7a00ae86a2e9482c91170aefe93f4ccda06c1ac86c4de637c69133da59/wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c", size = 110193 },
+ { url = "https://files.pythonhosted.org/packages/cd/cc/aa718df0d20287e8f953ce0e2f70c0af0fba1d3c367db7ee8bdc46ea7003/wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b", size = 100460 },
+ { url = "https://files.pythonhosted.org/packages/f7/16/9f3ac99fe1f6caaa789d67b4e3c562898b532c250769f5255fa8b8b93983/wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab", size = 106347 },
+ { url = "https://files.pythonhosted.org/packages/64/85/c77a331b2c06af49a687f8b926fc2d111047a51e6f0b0a4baa01ff3a673a/wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf", size = 37971 },
+ { url = "https://files.pythonhosted.org/packages/05/9b/b2469f8be9efed24283fd7b9eeb8e913e9bc0715cf919ea8645e428ab7af/wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a", size = 40755 },
+ { url = "https://files.pythonhosted.org/packages/4b/d9/a8ba5e9507a9af1917285d118388c5eb7a81834873f45df213a6fe923774/wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371", size = 23592 },
+]
+
+[[package]]
+name = "wsgiproxy2"
+version = "0.5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "webob" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f0/ae/cad3131f771a38b4cdad6ca82bfee1800afc69758c70d0e70483ed1f6b30/WSGIProxy2-0.5.1.tar.gz", hash = "sha256:0d9ecb141de720e2fd4f7a275a4a83a961ffeb6717483d940021ffa1c46f665c", size = 16565 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/4f/b9/472013e536aa22eba099becd8d1c8cddc1fd900303c60c75a643a59e41a3/WSGIProxy2-0.5.1-py3-none-any.whl", hash = "sha256:37ab414dc568aba8c1fb0660885d05ab7ddde0a3460af90fea415afcdd7dfca8", size = 9190 },
+]
+
+[[package]]
+name = "wsproto"
+version = "1.2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "h11" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c9/4a/44d3c295350d776427904d73c189e10aeae66d7f555bb2feee16d1e4ba5a/wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", size = 53425 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/78/58/e860788190eba3bcce367f74d29c4675466ce8dddfba85f7827588416f01/wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736", size = 24226 },
+]
+
+[[package]]
+name = "z3c-caching"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-browser" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/37/61/56cbfa9303a1f3c21ce5e2c6ced59ea64c8adeeb30276149f443cfba1b97/z3c.caching-3.0.tar.gz", hash = "sha256:81822a6bb3db87984fb8a7251918d7228989a4b83e58d83292d0247e1830aa0b", size = 22135 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9f/85/eb0bedbeaae7e4be658b9963ae5261286fc0cdd4f678c3943fa6cecbe3e9/z3c.caching-3.0-py3-none-any.whl", hash = "sha256:ee30d9848f571c173e07f26238a28e8856e2570577478bc4a59f331c8bc3bb63", size = 20568 },
+]
+
+[package.optional-dependencies]
+zcml = [
+ { name = "zope-configuration" },
+]
+
+[[package]]
+name = "z3c-form"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-browser" },
+ { name = "zope-browserpage" },
+ { name = "zope-browserresource" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-contentprovider" },
+ { name = "zope-event" },
+ { name = "zope-i18n" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-site" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/cd/3d/1df765a5a41dfa2387ce6061421fa6127c67d17c787d917b9a30d11de6ac/z3c.form-5.1.tar.gz", hash = "sha256:b3f310d48ae2b9d9269180b01c06127b8fd3aa5abb5bf4a26467de49cd1c8872", size = 368038 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3b/c6/585c1399fc085d58aef19fe51c1fda0073c2ae61da084ab4f2ad16f61472/z3c.form-5.1-py3-none-any.whl", hash = "sha256:a8ed55af5e4ee21aec0e3b49efd3e20257531439a3513577e86f7e5e3b8f47d0", size = 441937 },
+]
+
+[[package]]
+name = "z3c-formwidget-query"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "z3c-form" },
+ { name = "zope-component" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9c/d7/295b68f75bbfef66dde03098960a7ed39b109618597182f358d61fd9af23/z3c.formwidget.query-2.0.0.tar.gz", hash = "sha256:b99cb9e904dda57eab72143d80862d2f1421df5af8bda4b7b74a3e715cb98daa", size = 14311 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/45/3a/ed95bd15fbf212c13de518db1ac3889e156ef057798d9990a81098c32021/z3c.formwidget.query-2.0.0-py3-none-any.whl", hash = "sha256:2b2e4741514dae43af511c34b10181ecdef7b2fdf812d265728c87d697713a8a", size = 15813 },
+]
+
+[[package]]
+name = "z3c-jbot"
+version = "2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-publisher" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/17/03/df8ff6c7f53c9e9af6d181b9781ee22804f921544a79f7bf66f552e9385f/z3c.jbot-2.0.tar.gz", hash = "sha256:36531576fcf19e6fefaec22714430d750f65ff39c4ebc3cdb1c62c1b23bec23b", size = 17159 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/36/28/2640b58eb43974fef16dab064982cd25baece30c0a8d4589498f4bad60a4/z3c.jbot-2.0-py3-none-any.whl", hash = "sha256:ee7e0d70d7fcbf46b85a126c389c5a0f5dc1d37d9e70052e95fcbac4dd8c7c49", size = 18264 },
+]
+
+[[package]]
+name = "z3c-objpath"
+version = "2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a6/22/453702a2bf6f7e70a2d70cc5723b9084077ddb8e207b544fc24968d1901b/z3c.objpath-2.0.tar.gz", hash = "sha256:c7a072e5dc5223228e83f179fdf2c15fe2af8cc8ac46d8377c27854a235b88f6", size = 6809 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/11/1e/5d81e8bc4256516f12583bb3f769adf974c15704d273cd0b748bc5c5fb31/z3c.objpath-2.0-py3-none-any.whl", hash = "sha256:c25c8c6c0650716041b7b8cd45b58ef535d2742d4a8018b02351fafccf48a177", size = 7106 },
+]
+
+[[package]]
+name = "z3c-pt"
+version = "4.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "chameleon" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-contentprovider" },
+ { name = "zope-i18n" },
+ { name = "zope-interface" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a0/bc/ddce4fd09343f44a1479a425d8f04ec494311c03331044e37df0e6afa49e/z3c.pt-4.4.tar.gz", hash = "sha256:ba4292f1ce475d6da0efd5406d141a53bbca3a66bbedb4c97e43bd3f5bbf9190", size = 68261 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6a/5f/f68a6b6a6cc1da57e3fa44ca7134b19ba7975adf9226458242968cc6be91/z3c.pt-4.4-py3-none-any.whl", hash = "sha256:2ebe922a4bcc54ce2914230044eb190408b66b1f55a8407a3fe2ccb0a595bb98", size = 40449 },
+]
+
+[[package]]
+name = "z3c-relationfield"
+version = "2.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "z3c-objpath" },
+ { name = "zc-relation" },
+ { name = "zope-intid" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/95/d1/dddc25d210e7fd2b0cfdc0b9bb313c7b7c029fc158d0cc1f34278623b68b/z3c_relationfield-2.0.0.tar.gz", hash = "sha256:3c72aa77d9720c4b9b2ffb210e95d520c6b44118ebb546da7422f2bcff321ed2", size = 33217 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/64/16/6b91ee992e4a01fe655fdbcdbf0a1d53cb084b5dedd49b1a9eee3eb5c824/z3c.relationfield-2.0.0-py3-none-any.whl", hash = "sha256:7a606fe2b0f5ca68819b1041d0cca407cb64be50fbab8bb16467889e91a16fca", size = 26154 },
+]
+
+[[package]]
+name = "z3c-unconfigure"
+version = "2.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-event" },
+ { name = "zope-security" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/71/43/db64e9cc1f3109ead9f33aefe9183b3945c39c804beeaa458da8d7dbcdd7/z3c.unconfigure-2.1.tar.gz", hash = "sha256:f43cf5cdb062e5ddf756c619221f0134c3cedc3019fe9c679c8c0578ebe9e386", size = 12624 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ac/72/dd692d44567832dc878362c8e40926083f0fafd3aa3dd45092a706c2106b/z3c.unconfigure-2.1-py3-none-any.whl", hash = "sha256:fc0dd7ea7b9afada9dfbc16be323e04b20539211ae8ecf50c9fc8e05db4332c0", size = 14392 },
+]
+
+[[package]]
+name = "z3c-zcmlhook"
+version = "2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f3/da/09f14b2cc3d34270c3ed01521f07e1f484f92d8af0afc29b292aecac7086/z3c.zcmlhook-2.0.tar.gz", hash = "sha256:21078e39af9579ceb9c25b56e0283b0959b0d7292fbe5187dc0ed75ffe5cec04", size = 8269 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f1/7b/12af6c2cbca827922fd2960aa219f6e05ce8b3bef7a5b62d244031026915/z3c.zcmlhook-2.0-py3-none-any.whl", hash = "sha256:6899120a092eca16eeacfb0223b6c03596ae82e9607505c8e9ee497aa56f944d", size = 7750 },
+]
+
+[[package]]
+name = "zc-lockfile"
+version = "3.0.post1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5b/83/a5432aa08312fc834ea594473385c005525e6a80d768a2ad246e78877afd/zc.lockfile-3.0.post1.tar.gz", hash = "sha256:adb2ee6d9e6a2333c91178dcb2c9b96a5744c78edb7712dc784a7d75648e81ec", size = 10190 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a7/aa/47f00f32605177a945f3a1b36a1b2bb9a39260566541280fcee27cbff5cf/zc.lockfile-3.0.post1-py3-none-any.whl", hash = "sha256:ddb2d71088c061dc8a5edbaa346b637d742ca1e1564be75cb98e7dcae715de19", size = 9770 },
+]
+
+[[package]]
+name = "zc-relation"
+version = "2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-testing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b6/d7/4fa6191cc0c14688a1f5ddb5217d846fd1a060e84a3051fe9657d1bcf8cd/zc.relation-2.0.tar.gz", hash = "sha256:73493dcce01b763450483086f047a226e9f5d0dd8b233d7ec602b2ff5deed963", size = 150539 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/04/a6/e10fc8a71f4d6fbcb30a3852a45848ff109bd6015909d8cfe54c8b30a507/zc.relation-2.0-py3-none-any.whl", hash = "sha256:41461015747508ca66becddd222838bd6246e2909cc3c9fd922b7e0705da009e", size = 111687 },
+]
+
+[[package]]
+name = "zconfig"
+version = "4.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a7/69/cf96f0bb7e9ba45c7909401b1649922808033edc34857274cd5d3465e50d/zconfig-4.2.tar.gz", hash = "sha256:a0e4b5277c4cee8060ce335a578ac458f82c240ae96b16659200dbc4d98bfcce", size = 127198 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c1/f9/99a7b04ab682f7c532fe0e53cddb7670218b0bb4ae26e4056ca5e5fc0a8c/ZConfig-4.2-py3-none-any.whl", hash = "sha256:43ae4b70aeb30db44341863d480d739d1fba4534796a2f46f4ce4d99e075250a", size = 131399 },
+]
+
+[[package]]
+name = "zdaemon"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zconfig" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/1b/8f/d2e2748ab114b577b10889873cb370f7faf3ace5ce9b9b36a450452a2bd5/zdaemon-5.1.tar.gz", hash = "sha256:22e9fe5050eaebb9e03d9ad64e4f63ccd85e04c38fdb351cf113bef6f68db7a4", size = 60726 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d7/14/17ae4ef5c94ee3e5508469511a3fe09d20b87f214ffc20c7a4123f43cdef/zdaemon-5.1-py3-none-any.whl", hash = "sha256:e84327546e7c96613925d87b2eb204ff9c17d6343f9f81b28e3c3f52687fc4b3", size = 57019 },
+]
+
+[[package]]
+name = "zeo"
+version = "6.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "transaction" },
+ { name = "zc-lockfile" },
+ { name = "zconfig" },
+ { name = "zdaemon" },
+ { name = "zodb" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/1a/85/ab008e84445dcd39b2d079fdc7eb5475d5597de9504e2a0cb6bb44ca9a4b/ZEO-6.0.0.tar.gz", hash = "sha256:be238b5abf9ea3396935b33530f66a9afa61ccf8b6b813c2cfdcb2aa18541be7", size = 243635 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ce/36/dfb1aa57d58f39745dd97873c10be8568e4b19ec2c5d139dc3c62ccd70e5/ZEO-6.0.0-py3-none-any.whl", hash = "sha256:4fd6569e00a6f9c91fdfe7d917887666893252be7c0a6e4afc3901ef8d4b4ae5", size = 247161 },
+]
+
+[[package]]
+name = "zexceptions"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/1f/4c/c766014d7f5d31dea4c78948c7471305e643f2787753041249c07751cb78/zExceptions-5.0.tar.gz", hash = "sha256:ec1e4003b0ec6b5e4ca150f64e3366a44978587afd84a38de8d4b64674e1a678", size = 15263 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6c/4d/8158d3f93c7eac8c94e0cff3ce5472335f46c5dc2f8c572742e9996e7aa1/zExceptions-5.0-py3-none-any.whl", hash = "sha256:bbd11d5544f6611ae1045214f9fe5d0d95cd6c479a555de509fa1d41199491de", size = 17003 },
+]
+
+[[package]]
+name = "zodb"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "transaction" },
+ { name = "zc-lockfile" },
+ { name = "zconfig" },
+ { name = "zodbpickle" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f6/05/839fefc57001152367e62027667ad9190b1598a101d0e03ef1908e9b94f4/ZODB-6.0.tar.gz", hash = "sha256:e51c792115c5daad4e806757bafa2f754c000c23e6babc3be5e40775fe49b5dc", size = 786862 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/29/5d/8604d9eefc656459f487fae4ef1d70f930d9290212ca995de7efb2430a59/ZODB-6.0-py3-none-any.whl", hash = "sha256:271c5b2cf488f2b3045bb431a2ffc07b69fc3fdba9938587ff8ad37affb2ea43", size = 417758 },
+]
+
+[[package]]
+name = "zodb3"
+version = "3.11.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "transaction" },
+ { name = "zeo" },
+ { name = "zodb" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ae/0a/27521b4102a47c205f3a40d1bb117365bc3f5e6df0267413404e159469c4/ZODB3-3.11.0.tar.gz", hash = "sha256:b5767028e732c619f45c27189dd001e14ec155d7984807991fce751b35b4fcb0", size = 55094 }
+
+[[package]]
+name = "zodbpickle"
+version = "4.1.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/76/b8/005faae718f804a1cc01b83beed8bee1a245a1a214dfbfb8e7f3cac20c43/zodbpickle-4.1.1.tar.gz", hash = "sha256:dfc0c915ef1499dd0603970f5c1102c6bd7eb7b6ac46434b29a6d840bf027248", size = 117585 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e0/a1/77e75fdc15ed9b7bb47369be7d7633397649a58238535231f8e5b5a9d4ee/zodbpickle-4.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:316e527853c3e7450f54590b38f5dbe6a0f28d65431f305d1c593c83ec8249b2", size = 141769 },
+ { url = "https://files.pythonhosted.org/packages/da/a8/024a1a4d30cc8063509869cd88435f6cb1ca5ed615a4e054d11bf38079e9/zodbpickle-4.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9d5cd3f58c2a0a939736cd7591ea5eee9a79a542e5c7776bf3d1f0e36d6154ca", size = 140508 },
+ { url = "https://files.pythonhosted.org/packages/44/be/cdcf7fa71e0abc779d4035b1544c61b6e044607cda187caf55836f80d366/zodbpickle-4.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdbcf945a35cef7f37626fb9c0b638527e2b58acac805bfad287b0f92ce462f3", size = 305797 },
+ { url = "https://files.pythonhosted.org/packages/c6/fd/7c5c98230fadd0527caf6e98996db7e15af1ac694cb32b53223b6de65e1f/zodbpickle-4.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db939e16984dc4337505d550db920b3ba7b7b2459352bbed92258ba3337399a3", size = 305025 },
+ { url = "https://files.pythonhosted.org/packages/15/ba/3a2a91911331841ae2bc52f20fe7bb480ebe5aa20c6872420b9555a63fe6/zodbpickle-4.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e3b3dffb8dd3fbf122cb5f2526cd520659f1b38297010a9c63bf5a9c60274d6", size = 302456 },
+ { url = "https://files.pythonhosted.org/packages/6d/f0/da2724a996e0ca7776f93a7dddae9648fc111e519f5ace7593f134e12609/zodbpickle-4.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:feb3f6033c427f2cac261e14a7b5970a24feb6bb306877b35f2c82913f77314f", size = 142565 },
+ { url = "https://files.pythonhosted.org/packages/18/71/c3be0ac2d54b5faff705d3d6b00e23d1dbc1997a474c1accba64b21c3565/zodbpickle-4.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:031603c84488391ff23e5e12c5cd7f32055fcf468fa6fb5abbe8c7667ed3c510", size = 141833 },
+ { url = "https://files.pythonhosted.org/packages/ca/7c/6b3111f0cc178ae36a5d3d2d3fd932b1a3b089d97404128c49dc5bae2656/zodbpickle-4.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:30034eeb0783812f32ed527904836acaef59b4d0169d40d309882a3c231d260c", size = 140563 },
+ { url = "https://files.pythonhosted.org/packages/ef/bb/bc55053e92dfd29def5c0b587f50a54f55e4a7afdfdd87f78f73959c4114/zodbpickle-4.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:406154f36899455db07169b760a49019a925e3339851d5736a88d67f4f613e30", size = 306621 },
+ { url = "https://files.pythonhosted.org/packages/00/09/fb49a034cf9e7e3ac6abe6a14c9cbd6cdbf87c8d129eb8089afc5e5eb89f/zodbpickle-4.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e95b07af3d263f3e48f250d9712058eb8e9165084d583d2393bbb6d0a635e94b", size = 305881 },
+ { url = "https://files.pythonhosted.org/packages/71/42/2629cb924a37aa3cbd5456637224a6b06ff1c98f28bc1d1cf809eedb7024/zodbpickle-4.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f13642dd3276442997964c8f0055e1baebc42e19c8148ad228d60611eb4cf984", size = 302891 },
+ { url = "https://files.pythonhosted.org/packages/fb/c0/2d5c4bc9fd8c9d13f427e71c53f1e0c2f5f2ebe0555f3076db7afb59c69b/zodbpickle-4.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1cb666e73cd6c973a50d5ea976954c7c26740dc4de98fee4444f6d10ffa586d3", size = 142579 },
+]
+
+[[package]]
+name = "zope"
+version = "5.13"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "accesscontrol" },
+ { name = "acquisition" },
+ { name = "btrees" },
+ { name = "chameleon" },
+ { name = "datetime" },
+ { name = "documenttemplate" },
+ { name = "extensionclass" },
+ { name = "multimapping" },
+ { name = "multipart" },
+ { name = "pastedeploy" },
+ { name = "persistence" },
+ { name = "restrictedpython" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "waitress" },
+ { name = "z3c-pt" },
+ { name = "zconfig" },
+ { name = "zexceptions" },
+ { name = "zodb" },
+ { name = "zope-browser" },
+ { name = "zope-browsermenu" },
+ { name = "zope-browserpage" },
+ { name = "zope-browserresource" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-container" },
+ { name = "zope-contentprovider" },
+ { name = "zope-contenttype" },
+ { name = "zope-datetime" },
+ { name = "zope-deferredimport" },
+ { name = "zope-event" },
+ { name = "zope-exceptions" },
+ { name = "zope-globalrequest" },
+ { name = "zope-i18n", extra = ["zcml"] },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-processlifetime" },
+ { name = "zope-proxy" },
+ { name = "zope-ptresource" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-sequencesort" },
+ { name = "zope-site" },
+ { name = "zope-size" },
+ { name = "zope-tal" },
+ { name = "zope-tales" },
+ { name = "zope-testbrowser" },
+ { name = "zope-testing" },
+ { name = "zope-traversing" },
+ { name = "zope-viewlet" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/9f/04/d53a30e65c60cbf28ec51934b0eef594a3dced384fed44c1e8199ea725fb/zope-5.13.tar.gz", hash = "sha256:17efb7a5cfd5c40417b47d406edf8fce9e43a9da2cd013ba20d9d98719f1dccf", size = 12636820 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dc/69/870128f952851509a56c2ea604e2fe1a9af032c66a87172fd2bd733e12d7/zope-5.13-py3-none-any.whl", hash = "sha256:b0d0ebfa2787da62efaf37ba961e8a8c7caff0d248fc1f98844015aa07514997", size = 3203869 },
+]
+
+[package.optional-dependencies]
+wsgi = [
+ { name = "paste" },
+]
+
+[[package]]
+name = "zope-annotation"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-proxy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0a/7b/5285072d9a99724b86cb4c8783dd624c192966c3d231ed5722ad5869a4d5/zope.annotation-5.0.tar.gz", hash = "sha256:714c401a9a74f07a6447413a0f10ff2684f2712bd4e5f069ef98c54c42bab42a", size = 23388 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a9/1f/a0540cb8d297f835ee1afaa32ee9065ae0555fefe6264a2483f8069276bc/zope.annotation-5.0-py3-none-any.whl", hash = "sha256:d9bf817efcc2b63a1643bb632d6350e61caf5dd731eb1972cd01e97e2eb4e12b", size = 14138 },
+]
+
+[[package]]
+name = "zope-app-locales"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/d4/a1c09a67b03e8d7aa55fd77c77767978e58ffe12102f3915b50f887eff93/zope.app.locales-5.0.tar.gz", hash = "sha256:8bb1b11731ba31673e9d165f01f353089166d5bedf4ffbf4d1d72069b6b4fc59", size = 1168926 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1c/dc/5940716f9624d203c7b78b3691d3dbeb8068f8f470145e82115e1e682854/zope.app.locales-5.0-py3-none-any.whl", hash = "sha256:883119fc8159940223d4ea1cfae6a2300dd79c573f1b94c33e6e7624a98e974c", size = 1187885 },
+]
+
+[[package]]
+name = "zope-browser"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ba/f5/0a5ec6db335fd7e799f15e10dc8d127419d9175ea11464119a81c26f0bc4/zope.browser-3.0.tar.gz", hash = "sha256:817139e84077b23618fec1883ead262ca54d5bda450ee8ac6814505e226e66a0", size = 15305 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/11/b4/e82a492fc4d3626ae0fe4d4717b1b04f3427704c33b7a1fb336d5bb03c12/zope.browser-3.0-py3-none-any.whl", hash = "sha256:ba893e066258ae41881491f9bb4630e6cac50e53d17584e042bb81175e52b363", size = 7623 },
+]
+
+[[package]]
+name = "zope-browsermenu"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-browser" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/eb/49/4f72dded0fd0094204278e69942ca12f78a82282eab4a78ff091989a1c47/zope.browsermenu-5.0.tar.gz", hash = "sha256:8c066cfb7e12b40525eeeec4ec9905a635ea5cd46e5f16c950738792411fec7d", size = 24715 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/0f/7c2c754f9128a5b114c6b99c566dd1f7263b67371405cd28facdfa9f02a7/zope.browsermenu-5.0-py3-none-any.whl", hash = "sha256:9b2b5b5dc89fe11dd29f5f9a2e199cfbcc609055e59bf02ee5cda0afdc5ec61e", size = 30973 },
+]
+
+[[package]]
+name = "zope-browserpage"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-interface" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-tal" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ac/40/b03dd4bc87478001ebc714e6b538a264449d3db52249650d130b13f3be9c/zope.browserpage-5.0.tar.gz", hash = "sha256:62d8e983cf55d5a07df91c5f8ecb412d75c762ca31058a8ee336057b4662bb2a", size = 23785 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c2/f4/882df7f21a3d92d73a21ae30a03d109894af36666ae13b69401f3cfe4b0b/zope.browserpage-5.0-py3-none-any.whl", hash = "sha256:c67cade20d74744e36c281d450166b4300713c8064a285008ac635cc87ae21c5", size = 32082 },
+]
+
+[[package]]
+name = "zope-browserresource"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-contenttype" },
+ { name = "zope-i18n" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ba/8c/8dd615056921d3c555320303653212c082719f6b4339c3ddc7bad718c612/zope.browserresource-5.1.tar.gz", hash = "sha256:bd4c2545f13f565f2d977cc02b13a11b3f75fe8a87b8450f96842b15c0467744", size = 35585 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e7/ef/4b45d882fca365a9b67a0fc760875c082e7f917c14e384915c0fec2e7fc1/zope.browserresource-5.1-py3-none-any.whl", hash = "sha256:f02edad4c22942e7683d09c5e45fbb58f5d0b24a788daca973015f87b9fb411d", size = 40577 },
+]
+
+[[package]]
+name = "zope-cachedescriptors"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/43/57/ad4078768d4c6557b1a0df5a3fb117bd1d54785b4a0763648304b3388560/zope.cachedescriptors-5.0.tar.gz", hash = "sha256:3157be866fc9724d077a8b5bf6c3fc21c38a4147ab664e724622dfe5faff048a", size = 13250 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a9/3b/508a9a15414f5ccc9b0aa2dc13acd87159f664ff1e5058bbfd1e4853f501/zope.cachedescriptors-5.0-py3-none-any.whl", hash = "sha256:7ee05950c12c241104c9c91530f128d9d96d43d260e0b57864382ee2f3272f8b", size = 13146 },
+]
+
+[[package]]
+name = "zope-component"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-event" },
+ { name = "zope-hookable" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/53/32/87db95f4a5f097aa837dcb951f5a4754e2e8d3ac70160a6c2df7bd215956/zope.component-6.0.tar.gz", hash = "sha256:9a0a0472ad201b94b4fe6741ce9ac2c30b8bb22c516077bf03692dec4dfb6906", size = 90268 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/ea/18a5e07ce7f66714aa289ba21c5bc52221bffc3a77d6e4318d50e8a0a3f7/zope.component-6.0-py3-none-any.whl", hash = "sha256:96d0a04db39643caf2dfaec152340f3e914df1dc3fa32fbb913782620dc6c3c6", size = 68841 },
+]
+
+[package.optional-dependencies]
+zcml = [
+ { name = "zope-configuration" },
+ { name = "zope-i18nmessageid" },
+]
+
+[[package]]
+name = "zope-componentvocabulary"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "six" },
+ { name = "zope-component" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/05/fc/08c1c82f45353c6bfc7b20f59e49c3f6a214f833c853d63b12625beca2f5/zope.componentvocabulary-2.3.0.tar.gz", hash = "sha256:e5b56a70ad523726e109f070ef1b68dafd1024f4a85698deaf8910da289b8d76", size = 11157 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ae/8a/851e7169c2b519e0a1b2ac94d6336868472e18251453b47b43bd35566664/zope.componentvocabulary-2.3.0-py2.py3-none-any.whl", hash = "sha256:ecaf563679f12be881c9c8484425638c224190fbe4b17598af73acd461cb6cf2", size = 12509 },
+]
+
+[[package]]
+name = "zope-configuration"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/05/4b/0b6bc5ffc29243ecb56681244dc87d04db83f58d50bd2f58d6a962d26199/zope_configuration-6.0.tar.gz", hash = "sha256:da1b879bd41138fb809e341b3cbd1e38f32b88f0cc88ee7e0f80a5aa25e68cfe", size = 84258 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/97/32/ec9fe5c67a5b549d7088d523dc3429392e3b57b0d6055f781e7ed2e42803/zope.configuration-6.0-py3-none-any.whl", hash = "sha256:1b99b4845c987fbb8e329a5548b7c4aa3b75ee5531dcc5f69674365a2f5e5306", size = 79015 },
+]
+
+[[package]]
+name = "zope-container"
+version = "6.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-component" },
+ { name = "zope-deferredimport" },
+ { name = "zope-dottedname" },
+ { name = "zope-event" },
+ { name = "zope-filerepresentation" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+ { name = "zope-proxy" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-size" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/10/d6/645cffd9592a979405d332da6c5e5759e71c064d5d546362e1758e929066/zope_container-6.1.tar.gz", hash = "sha256:8e3f1ace03324defddcc28a1c851c3b2565c098bc17a0b76ac044557fecc9cf1", size = 72829 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2f/d8/8290978f0bd138a5a7529a0eaee116807b99e3c7ed4117d6154d3ba7dcca/zope.container-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44301b824c30cb2f8edafcd7908e59e24979b20c41ec24b0449f1ecf0c926193", size = 76331 },
+ { url = "https://files.pythonhosted.org/packages/08/80/0c74b0278d711a08439a4a4520da8f938e039e6e7b89aa0bf5c2e6f74fee/zope.container-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:335cff276acdb449be9cc82c0a32ab7505df190e7ab7296be2da48378aae6694", size = 76722 },
+ { url = "https://files.pythonhosted.org/packages/67/76/02bed357c34298eb0de8c9aa4d46fd1867908b2a202a70b5989042f766b0/zope.container-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58e350f177946adc7ea16acb30eec424b71b66739eccb9b4fc909c495d5c4cee", size = 116582 },
+ { url = "https://files.pythonhosted.org/packages/35/8f/ba57f80c375e1ac6c71cfd055183ebf5de8cc693d8ac95949c72765ce116/zope.container-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28e37d136f82bc3f57e322580c607a3ac4da39c0d526d1cddbc0943ae4e55eb7", size = 110909 },
+ { url = "https://files.pythonhosted.org/packages/1c/28/885ab38c1bfccc386ed04b72af49cdfb5a140945b5e98f9818ee2a5773d4/zope.container-6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d70f865264e66ba30310ee4533ca7be4e9a398b02d97b3d5a79de517b3eb3a", size = 117384 },
+ { url = "https://files.pythonhosted.org/packages/91/f9/cfcc82a740cef29e119bc325dc3ae740e55b5e932f0d2e2966410b2a833e/zope.container-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:27f112dd498c8d7ffc90c2710cb393aa677660162760d33f3703b2d34d044c5a", size = 78145 },
+ { url = "https://files.pythonhosted.org/packages/ad/0f/c6e30db7a142fae0a6f4fcfcefc26345bcbb2cb2555f1a70dc94a29c10ed/zope.container-6.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:fa1328c996979904a2671825917c59b3a7642d75406e23a8ade642b754652c65", size = 76338 },
+ { url = "https://files.pythonhosted.org/packages/4a/4c/dbf6861a3c41a0a906e6b288abf20e3c9dcc6d303ea3b7c2bb0fa610256d/zope.container-6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:46feba09c2c74cfe57a9591c4694f1492ad25f26455d60d9a3ea979a24e6c6aa", size = 76723 },
+ { url = "https://files.pythonhosted.org/packages/0e/ba/dbe5a9cfb490fe60e83e67b94eda4e11083bc0b97ce5654e056bf0715d41/zope.container-6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e183199bc81eeede2525c2f63146024d3648c6873dea44ed88c1bfcfa0f9ed4c", size = 116554 },
+ { url = "https://files.pythonhosted.org/packages/c1/96/9dfc80bcb24ee500088fdba108051b54b44f25027e2d75023ea194256490/zope.container-6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4148fa308895bccd960dedd3269164656063db8b08fbb0df2e23c67283da22b", size = 110916 },
+ { url = "https://files.pythonhosted.org/packages/db/d3/6cfce81520150127a1f94a5ca94c3c6f4b8e40c249abf40e065ca875763a/zope.container-6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fddeb39ea15d05f0c77e1177873417b6c7dcf03cd3fcac60cc63309e97d0fca", size = 117354 },
+ { url = "https://files.pythonhosted.org/packages/f6/63/f3cf224e3ae2b5c310e47378bd16beaa28ec2ddfb0678ffcfa9144cd00e4/zope.container-6.1-cp313-cp313-win_amd64.whl", hash = "sha256:661e34a13a3eb9c3870528d6fac953a0db448614b85dce7aff78185f04d7cebd", size = 78154 },
+]
+
+[[package]]
+name = "zope-contentprovider"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-tales" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ba/49/51e90a4cd9feaebbfd93f2bea7bd54a849e498cd72fcf2f1b9fdf2460933/zope.contentprovider-6.0.tar.gz", hash = "sha256:9e6fc526664ac2126071b26a9b10f4baf1e169808fbcace73fce529d7c20a1cd", size = 22440 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f6/09/2d9a44c1b0ce075ac9e2f4456d25316c7d0b8dce94c6e1fc2574d96202e1/zope.contentprovider-6.0-py3-none-any.whl", hash = "sha256:3c8567553058e3f24687bd019f1ec7101d8e4b48f39f05e6d051469d5ce17db4", size = 11227 },
+]
+
+[[package]]
+name = "zope-contenttype"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/40/73/2d056480dd7ed2647eafb3cfb1509a076793432bfb20394da9a2df4c6052/zope.contenttype-5.1.tar.gz", hash = "sha256:0001ef1b65ca650519056dce530c58d0b396957ccf0502323c8a1549db64d317", size = 20469 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/19/42/7b13bcca3fdf4f5970faf4b1be8904716a291e0b61451695615834a1d1dc/zope.contenttype-5.1-py3-none-any.whl", hash = "sha256:e3d029016cff3ef0a17f03281c3e12006acb14f526cdd185876ddc19945d4581", size = 14288 },
+]
+
+[[package]]
+name = "zope-copy"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zodbpickle" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/72/d1/118f7daa4aec1e05ea86d0bdf45323c50c131db0892fa6b7db7680da2b5a/zope.copy-5.0.tar.gz", hash = "sha256:395e2a43480faa632ce05ea71c4a272ffd2b7c14aabe1cc97f19a8ca26d155d2", size = 22981 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5d/69/6d9fee5ad57f0cb2e07074d256d8f0be4e2179bf7a13784e5d8d89ce6908/zope.copy-5.0-py3-none-any.whl", hash = "sha256:efb3aad81a4b1ce853c8d16e1d1dd6c50696f6c8a84532ecc675f0560249aadc", size = 10099 },
+]
+
+[[package]]
+name = "zope-datetime"
+version = "5.0.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f5/c7/bfb29f9747b487c6bd88dad6a5dad80bb6e92e91341fc648b1ee4998ff08/zope.datetime-5.0.0.tar.gz", hash = "sha256:c0d03970ea62b8db23694423d866e53778e6646ce8595f7b16ae6a185b69cec0", size = 48845 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/44/b1/8648b63d8e00e302e43426bb91a10449f8115d31b8401c45556981f5d0a8/zope.datetime-5.0.0-py3-none-any.whl", hash = "sha256:b3c0574585fdf77fb2825b6137c2013cf23bb1dba16a2fe83c7d2f70842daea0", size = 43374 },
+]
+
+[[package]]
+name = "zope-deferredimport"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-proxy" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/a1/b7/9b0c93edb4c6745ac8784c265d244f5b3bc4082d92f7aefe952aaa5be5f3/zope.deferredimport-5.0.tar.gz", hash = "sha256:3abbf0e18c1f1765914ecd1d41b549e4d045b21b28e4065fb0c1de0ad736b2c3", size = 19386 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/69/f7/b5e232857f4d511b2628697bf2e48fca55ea4ed75b1432efd1bf024fbd12/zope.deferredimport-5.0-py3-none-any.whl", hash = "sha256:b26e013b02fd1ee3e26510db66a737105128e48a0d348490f7c901ffd1928f25", size = 9977 },
+]
+
+[[package]]
+name = "zope-deprecation"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/48/22/0e621e31b5826b2ff121fea5b1ea91173c88f86e182181f012abcc84a51f/zope_deprecation-5.1.tar.gz", hash = "sha256:46bed4611fb53edc731aadeb64b28308bcb848f4cc150c60c948d078f7108721", size = 24453 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/30/88/5fc32633682a452260f50417da3d4be26137dd220ef617bbd8ed52f0cfa9/zope.deprecation-5.1-py3-none-any.whl", hash = "sha256:60f957b964d8f947a4a592c647d51ce0f4f844d1f041657956ddde0d9fa9a76a", size = 10020 },
+]
+
+[[package]]
+name = "zope-dottedname"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2d/a3/c372c3c29772a91fc3387f25e8d239297f59b0dca6ec6e0cdb0416e28dd2/zope.dottedname-6.0.tar.gz", hash = "sha256:dbc4b85bfbf34b1ef88dab16252ac6ef16d90439f2223b2d0a262cf419eae902", size = 17140 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5b/5f/04026e33ceea0347d60ceb9605523fc30183cf180f0bd165f9b674478007/zope.dottedname-6.0-py3-none-any.whl", hash = "sha256:023fd3e0790d1dca912c05667e9490f137d3bf124f5954c85214cba67bcd9290", size = 6420 },
+]
+
+[[package]]
+name = "zope-event"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/46/c2/427f1867bb96555d1d34342f1dd97f8c420966ab564d58d18469a1db8736/zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd", size = 17350 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fe/42/f8dbc2b9ad59e927940325a22d6d3931d630c3644dae7e2369ef5d9ba230/zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26", size = 6824 },
+]
+
+[[package]]
+name = "zope-exceptions"
+version = "5.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/94/85/b4947d4c04b8e49ee53e60cd834304e7d6a0392c4b587ab658f13389d500/zope.exceptions-5.2.tar.gz", hash = "sha256:4cba3248678773bbac6faa3ae3537df09a843881b89fb9e81aca282f3b92b2f3", size = 31520 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/dd/31/a54159a96776b55e7460e22fb77fb31b48b83a8c4f5a7f720adc4476c45c/zope.exceptions-5.2-py3-none-any.whl", hash = "sha256:5c1182ad31ce5db2419cc4b6581a221f20582cb3bc8468568342661897974874", size = 20002 },
+]
+
+[[package]]
+name = "zope-filerepresentation"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d8/05/0001ada679e13c639139679fd49bf7195b3755d683c4bb21fc1e898a1d38/zope.filerepresentation-6.0.tar.gz", hash = "sha256:cb36b7886b29276f82f1685f3f291f4235e669cd8785d14742d465d13aef6aab", size = 15288 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/91/02/8100ac284eab14a6f2cfce4454cb0bc39c55cc9c3d34d1a9c0deec768219/zope.filerepresentation-6.0-py3-none-any.whl", hash = "sha256:7e1d486faeac52d64fa4620a44c694140ae14c03f58122a81cbf67bb9eb3fd6a", size = 8300 },
+]
+
+[[package]]
+name = "zope-globalrequest"
+version = "2.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-publisher" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/10/3a/ae324d6de3cb543f21d94b635b0344db09ad4e531e7e33b4c88e5a2e18cf/zope.globalrequest-2.0.tar.gz", hash = "sha256:2b1f4b2ec549c7baf381b0882be58569c327ec2171d1b0aa0f4c7b23630836ab", size = 6623 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fa/68/6b21fd5c6f0f84d3e99e2c782159328ea4a4ee26eacd58e39ce9d2ff177c/zope.globalrequest-2.0-py3-none-any.whl", hash = "sha256:372fdb35188377a4b41b767fe5d103c0bed97e9e3f37c64d56c238a919fa1819", size = 5678 },
+]
+
+[[package]]
+name = "zope-hookable"
+version = "7.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ca/ce/293f46f71beff79a17b7c6a81ad04a3e1d29196cc23e2f01cf240678c888/zope_hookable-7.0.tar.gz", hash = "sha256:ffd25a6706789752f307d1ee65d23d47436ebf30d1095f14584ebbd03bf921f3", size = 21392 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b0/dc/228977874b98481cf2f591d09b74022ed2ca348d4a1b8c94b4ae4ffe0af5/zope.hookable-7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6994ab3cf8cefa39cc820f09faa2b7eef01b4e13fad40a11485960cccf65dc12", size = 14340 },
+ { url = "https://files.pythonhosted.org/packages/3d/12/46ddbcd926b8368494e379d4fe92230648e3eccf56121514329663fde7e0/zope.hookable-7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e8573a44557f32942c9cf4f49673562c44c4ffbf7029774104363002d9acd25", size = 14918 },
+ { url = "https://files.pythonhosted.org/packages/10/bb/86de04222651d20f66f805ac08fa4a02127de6243971031d784232b11b83/zope.hookable-7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6fc2ea7cc52c447ab47cc2b8e4639b3b511fc0eed58ce62abfffec38d52f99", size = 26334 },
+ { url = "https://files.pythonhosted.org/packages/9d/6b/c9e5160ff3d84bc0ecae9679ae424fb064b1922cb05bcbf3eca922ea46fa/zope.hookable-7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1801e2db7f4aa917fff268e261d783fbcd7ed9ab70e22dd65553ed6ccdb5505", size = 24965 },
+ { url = "https://files.pythonhosted.org/packages/68/74/a0012278a28e2ab3bf5fdc84f6f1c57a3f690419a9f2d5af19f113b468b8/zope.hookable-7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:718b600cceed31c0af4e799490e851cd54c761467b7e1ac7dec45a997fc56116", size = 25968 },
+ { url = "https://files.pythonhosted.org/packages/27/b7/05e2fd1434aa05f4339e556f6ca56aaba4766337ed4e5744319803cbeab8/zope.hookable-7.0-cp312-cp312-win_amd64.whl", hash = "sha256:5aef76cc5cb5e2a9c65d5561559a0a599aae7d69e89fb3d5eb565709886f62c0", size = 17789 },
+ { url = "https://files.pythonhosted.org/packages/9c/92/d5effcccf17caf8bc16a4113090b08a654cf4e9fdcc01f95d5f562e10f2f/zope.hookable-7.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:cbcf040de78e20ba5a921c611cb82f092d361f3a4c161da621ca964328698114", size = 14345 },
+ { url = "https://files.pythonhosted.org/packages/08/23/96aaa20655c7449b71f9dd22e341a749bb2a01e8817460df067c88182886/zope.hookable-7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5e77e3990a72228439b3c92d5ae6298841c9ae8892a846b479baf7cdeaf6c504", size = 14917 },
+ { url = "https://files.pythonhosted.org/packages/f6/90/58f071e552206de0e7cf3771a51ed85305b7fe1a261d33aa04981d1a09e8/zope.hookable-7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a835c2d6da5754a468ea9cc938e36087dba49baae820cf64e93eb0a6119e02ef", size = 26311 },
+ { url = "https://files.pythonhosted.org/packages/af/70/c86419d4154f5edcbe04597d52840c28a74f19c9f6fe21e52e062d19c144/zope.hookable-7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:638f9ff9d49ceee5e816b650f823de2c2cf43cb5579ef82b6457f34ba49b13d3", size = 24981 },
+ { url = "https://files.pythonhosted.org/packages/b5/55/2be4d0524b23bb1177f0adafaed9569dead8466a8d03d9520512db08cd32/zope.hookable-7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83a39ca0834ca2e5f201cabe04aed16a68d370b66b44b4b8492914518869a34e", size = 25953 },
+ { url = "https://files.pythonhosted.org/packages/c5/ff/24eebe78521d4caa72583d336ecf34722bfccf4cad57a2150f62e198f618/zope.hookable-7.0-cp313-cp313-win_amd64.whl", hash = "sha256:5d507bb0be87c61e160221e00a09dc498f411df7671d27393162f44bce7b1ff1", size = 17792 },
+]
+
+[[package]]
+name = "zope-i18n"
+version = "5.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "python-gettext" },
+ { name = "pytz" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-deprecation" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b4/f4/ca818aeb87508a5eb6ca7b5137e11326b7bd8a78d51241c65e6f217deadf/zope.i18n-5.2.tar.gz", hash = "sha256:3417f222ec103458e391f23af72b822eae2e62af230e9a3beca82acb45fe9727", size = 619808 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/82/fd/b89f355aac2e03a9dfdd55d238c236bd16c1dfa68b15d837d131d5f1d00e/zope.i18n-5.2-py3-none-any.whl", hash = "sha256:229856993ed0ad5ed7b5e1b3b4f3e5d872087d90df69e0c8eabd2058c636a083", size = 799161 },
+]
+
+[package.optional-dependencies]
+zcml = [
+ { name = "zope-component", extra = ["zcml"] },
+ { name = "zope-configuration" },
+ { name = "zope-security" },
+]
+
+[[package]]
+name = "zope-i18nmessageid"
+version = "7.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/59/c5/58fab4c6a5a82a8e276adcb9f42ad6cf19ace3ee48e96ef4628218638f79/zope_i18nmessageid-7.0.tar.gz", hash = "sha256:bf9146078c0d7359da41043bd2b713203c4fc56ef2122b3cdbb7551c3fcd8464", size = 27929 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a9/3b/e41aa4a00510ca7edc62df4a0e46ec9725007bce7e82326b84ea55dd0614/zope.i18nmessageid-7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa1ae53b1bf2912c35001318c1eb9edd41a46d8282423faedc50d44a5f7b52e9", size = 17765 },
+ { url = "https://files.pythonhosted.org/packages/7c/1c/631f9fb2314802029a0fc3f1e8e974716341e690e8da60392948b14c9e06/zope.i18nmessageid-7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e3e0101ec6dd0d7e9c697166cc98058761b0ed4538c24bee89cecb5528bdc61c", size = 18354 },
+ { url = "https://files.pythonhosted.org/packages/f4/e9/1727ba213180d03d90067f54a62c2de351490ca92f752d554fd29c8c8935/zope.i18nmessageid-7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e0c80a7f824036acfcf046bbd9db3e14909aaca18c8cfc970794481d83c767", size = 33812 },
+ { url = "https://files.pythonhosted.org/packages/05/de/05457c704799ee08d3f16560d12d14134a935123fadcc6ff2959e9f14520/zope.i18nmessageid-7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2dc03e41f328238661b489344b97c0c305ef80f8ddb00fa2b16d7bca21d8ab", size = 32291 },
+ { url = "https://files.pythonhosted.org/packages/1a/07/d56b6a808264eb119bdccc0385779f99ea58aa552bc6f22702bf03d301a2/zope.i18nmessageid-7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31cb8788eac247aa6b8c0bf3e8cb781b1869a563ed44f7ac83bc269641bf7881", size = 33416 },
+ { url = "https://files.pythonhosted.org/packages/99/d3/f3cd78dba4d1c80af6802cfbed0600977075b5185ecd835210d4588c4515/zope.i18nmessageid-7.0-cp312-cp312-win_amd64.whl", hash = "sha256:5de47a4fd7a74e935b8f88c91cff38bfc8a02a0311e4bb66abc11e92cc43bd3e", size = 21327 },
+ { url = "https://files.pythonhosted.org/packages/d7/df/583fd4e5dba05b45b07db8ed10e8705bf090e29a29b8f070c521fd7097e6/zope.i18nmessageid-7.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:2194d5bb67fbae507501119b932692ef6cf59606eda9ce7aeeb77e7645c44d46", size = 17766 },
+ { url = "https://files.pythonhosted.org/packages/c6/d1/69c30572857e45f4ebac532c704dd29b8312eee9b28f4e1fd9cacccd8903/zope.i18nmessageid-7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eab9fdba09409a2895e27823a53d095127639cc9472a138511f4d826c35e6bad", size = 18358 },
+ { url = "https://files.pythonhosted.org/packages/e9/f2/375793b55182e47c5772f73e4fac91b6b194078d735ee6425aeb2a578b96/zope.i18nmessageid-7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f88c10ac7e795900a4a2ab680026381dda6d025d7ba09a334a23fb660db725e", size = 33773 },
+ { url = "https://files.pythonhosted.org/packages/81/0c/67532e19a0c5cd7cc4f596cf87638d777f7fb19a44a69ac3fd0a8a8795c2/zope.i18nmessageid-7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fae59dcc9f02b1f16ecf0abd10a4c8a3344ede81083d02f6572130c0f2dbd88", size = 32252 },
+ { url = "https://files.pythonhosted.org/packages/cf/3a/1436ad551c49b51a32f38917f9455442d027b3c054c0752553f7a194dfbb/zope.i18nmessageid-7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d955062da0bbe71d88514ffe9c1e74d454af55eafd5d8132dc7038ca42caa18e", size = 33373 },
+ { url = "https://files.pythonhosted.org/packages/f5/c5/9b3d37b3091cab968ef963c099f7c97e9d934848d8131409589abe719c99/zope.i18nmessageid-7.0-cp313-cp313-win_amd64.whl", hash = "sha256:e57778992999aa1e3bd2dcc75d2b3b26ebb5786e714bdabf0260ec63dfc4ab5b", size = 21336 },
+]
+
+[[package]]
+name = "zope-index"
+version = "7.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/aa/31/e883766f6520a16717f70b6d4291424c2ac8c1bc990e2ef6dc7b0a5867cb/zope_index-7.0.tar.gz", hash = "sha256:0dd8ac64dbc1e6f3b51065b98d3c0f2acdb91e0ccdfee17535a56feaf093f6e0", size = 76707 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c3/e0/9e1e7ba6c3964d94cdcfe81e972c860cd9779bf8237049ebdd139a1907e1/zope.index-7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5481f1f60034d721f2ff8efa5a00087b23435cf7a43f1637c8b51f929e46ff0a", size = 91417 },
+ { url = "https://files.pythonhosted.org/packages/c5/37/1743504d78c1de50d059b003377d3ff35287c41db9a29f8bf02c7836862f/zope.index-7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34183e317006f41efebfd9080dda6f9c72277078b1c23c7e8c861dc4caa7b2d5", size = 91883 },
+ { url = "https://files.pythonhosted.org/packages/8b/1d/ee6dc009747d19b1f4b3d5b81cdcca135c17a0913303a5808dc805174f55/zope.index-7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:043e5c907c2770e31b41ba6cad9a63e38acc767b86b6b8cb1dc91fc117890211", size = 101271 },
+ { url = "https://files.pythonhosted.org/packages/9b/8a/5b41108a4b7c273e123c97e181f137cc90708d7ac51d4e0249c78ff04685/zope.index-7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aaadefa7e0c6f7952409e53628508171812f56d00d139dfb44eae1573a5adae", size = 100333 },
+ { url = "https://files.pythonhosted.org/packages/c7/e0/6e2b973d37588e5947cfa472f3e64890a9f078a0f07af936490c2b73c437/zope.index-7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965b8c2f36b20557427b1c38b313bcc106ed2aff061cc2c9b724f42eca64853d", size = 100693 },
+ { url = "https://files.pythonhosted.org/packages/89/4b/8bbd09a44ea4eeab7d7ea23802c4d9011d6edb6dc8497ab7c4c9fcaf4661/zope.index-7.0-cp312-cp312-win_amd64.whl", hash = "sha256:819fe8601a01dbca34237eacf65c8af952d7ad2e118f61bab7ae7b7a0ff9b825", size = 95805 },
+ { url = "https://files.pythonhosted.org/packages/a5/74/91e3ed1db04435fc348852441a7a7525fd9e377ec39be28de82ca930b5a9/zope.index-7.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:20a34b01560aaf9bd7c562de2e9e0aa725e4653ecd506e25606ad394970680fe", size = 91416 },
+ { url = "https://files.pythonhosted.org/packages/46/5e/6fe55ddfdf346bf99af2919aa4a6f0877c5869b78254c9e405b72c538d69/zope.index-7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4639c40651cf94d8ab6ecdc81686f56d8063e3b107214b0f21aabe7f5eada2cc", size = 91886 },
+ { url = "https://files.pythonhosted.org/packages/fd/50/9e4ab358521988c84aaa7f4ba837c29a2833ee49503cb33d528e2bf2123c/zope.index-7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c43d9855eb80a259647fb0ebf5fe1bbd023ed95f26d04e8ce3ba9d456ac0001b", size = 101256 },
+ { url = "https://files.pythonhosted.org/packages/e6/73/e8eb7d7b9eb52996e1366f207d9b29bb293b757128c0e01626450dc942ef/zope.index-7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ffa1ee330cae29ec52eb3935c3d12cd47dda55b8c5a39b0ed803af5753ff01", size = 100320 },
+ { url = "https://files.pythonhosted.org/packages/eb/89/2e0212a88c928b01f3f85ed46918ed8c63ccd1659b7578080e592b50bc41/zope.index-7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dca21585f271f752db07176b3e4b0e5bf3af3b097ff0265eb741e9583bf69c", size = 100666 },
+ { url = "https://files.pythonhosted.org/packages/0b/7b/c39249e0bbad27d255c79890d3651074d1e8ac6efd679440b223164d5781/zope.index-7.0-cp313-cp313-win_amd64.whl", hash = "sha256:ce3589ba70f77cb902858079d1f90e414e25d246c5a1ad395c7ded3157509858", size = 95810 },
+]
+
+[[package]]
+name = "zope-interface"
+version = "7.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/30/93/9210e7606be57a2dfc6277ac97dcc864fd8d39f142ca194fdc186d596fda/zope.interface-7.2.tar.gz", hash = "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe", size = 252960 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/68/0b/c7516bc3bad144c2496f355e35bd699443b82e9437aa02d9867653203b4a/zope.interface-7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7", size = 208959 },
+ { url = "https://files.pythonhosted.org/packages/a2/e9/1463036df1f78ff8c45a02642a7bf6931ae4a38a4acd6a8e07c128e387a7/zope.interface-7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465", size = 209357 },
+ { url = "https://files.pythonhosted.org/packages/07/a8/106ca4c2add440728e382f1b16c7d886563602487bdd90004788d45eb310/zope.interface-7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89", size = 264235 },
+ { url = "https://files.pythonhosted.org/packages/fc/ca/57286866285f4b8a4634c12ca1957c24bdac06eae28fd4a3a578e30cf906/zope.interface-7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54", size = 259253 },
+ { url = "https://files.pythonhosted.org/packages/96/08/2103587ebc989b455cf05e858e7fbdfeedfc3373358320e9c513428290b1/zope.interface-7.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d", size = 264702 },
+ { url = "https://files.pythonhosted.org/packages/5f/c7/3c67562e03b3752ba4ab6b23355f15a58ac2d023a6ef763caaca430f91f2/zope.interface-7.2-cp312-cp312-win_amd64.whl", hash = "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5", size = 212466 },
+ { url = "https://files.pythonhosted.org/packages/c6/3b/e309d731712c1a1866d61b5356a069dd44e5b01e394b6cb49848fa2efbff/zope.interface-7.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98", size = 208961 },
+ { url = "https://files.pythonhosted.org/packages/49/65/78e7cebca6be07c8fc4032bfbb123e500d60efdf7b86727bb8a071992108/zope.interface-7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d", size = 209356 },
+ { url = "https://files.pythonhosted.org/packages/11/b1/627384b745310d082d29e3695db5f5a9188186676912c14b61a78bbc6afe/zope.interface-7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c", size = 264196 },
+ { url = "https://files.pythonhosted.org/packages/b8/f6/54548df6dc73e30ac6c8a7ff1da73ac9007ba38f866397091d5a82237bd3/zope.interface-7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398", size = 259237 },
+ { url = "https://files.pythonhosted.org/packages/b6/66/ac05b741c2129fdf668b85631d2268421c5cd1a9ff99be1674371139d665/zope.interface-7.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b", size = 264696 },
+ { url = "https://files.pythonhosted.org/packages/0a/2f/1bccc6f4cc882662162a1158cda1a7f616add2ffe322b28c99cb031b4ffc/zope.interface-7.2-cp313-cp313-win_amd64.whl", hash = "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd", size = 212472 },
+]
+
+[[package]]
+name = "zope-intid"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "btrees" },
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-keyreference" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/e8/02/4878cc89e24c0296402ad49bb6bd2a1e616b22255b208800bcad81b240f8/zope.intid-5.0.tar.gz", hash = "sha256:b6baee2982419c73e7bab5b089c19e5d01adbe252472face2239014979d2ad51", size = 20834 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cc/cf/5a8f491471f78fbc3e654eab844e0349296556be1d9f16dfd2755d5c4e0e/zope.intid-5.0-py3-none-any.whl", hash = "sha256:017baf29ce7396bd7b2aa7a0caa8e24273424274e33904d6e7a01230b02c87de", size = 12824 },
+]
+
+[[package]]
+name = "zope-keyreference"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zodb" },
+ { name = "zope-component" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ee/35/645eadc95947896dc999a33cf4ce2e1927b716fccfef17e4525e3d3773ce/zope.keyreference-6.0.tar.gz", hash = "sha256:a8242f4115befe9181d0b8f4ff847d213246f2c24a6a334f0cc8d103680c14d5", size = 19451 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b6/8f/989b9a7b87693c74696853dc02aaab32affd6e7a7877f5133fc208c1e11f/zope.keyreference-6.0-py3-none-any.whl", hash = "sha256:5a28c157df5417b259bde0925d3c13890c809714cd6557601d3ed8fd9cc107e2", size = 13305 },
+]
+
+[[package]]
+name = "zope-lifecycleevent"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/6e/6b/1129e5cfe99ad76a0987e9f00c5102c3d5219699e4dca5a0466337c2553f/zope.lifecycleevent-5.0.tar.gz", hash = "sha256:ead3fb496e7614f9b569d16dad4b78052b0ac21875bad8d66ca350352d9b6f9d", size = 24899 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/56/a3/f39def1937fbc94d080be0c1f064f101637140420d1935834f7f06185e11/zope.lifecycleevent-5.0-py3-none-any.whl", hash = "sha256:28431a461522e7a49f8e1e4d7541a73566747c70300ff4b6dee29e021e70540b", size = 18162 },
+]
+
+[[package]]
+name = "zope-location"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-proxy" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/eb/f9/1fb7a001feb5fec6f180ef3610169f1cbef76e8c015c52409c2d18b7fac4/zope.location-5.0.tar.gz", hash = "sha256:016fea934b97dad2b08a64ea7f2fbc3de55dbb074c461f66d871c70bf3aaaea5", size = 29020 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e2/7c/e444a20656d06eb993a0c1901063250399177d1d3632dda729542813681c/zope.location-5.0-py3-none-any.whl", hash = "sha256:7c7184fd5950f76b39c2df76ed9bd23d458877985ebad5a5b649e0b2ebbe37f0", size = 19033 },
+]
+
+[[package]]
+name = "zope-pagetemplate"
+version = "5.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-i18n" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-tal" },
+ { name = "zope-tales" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f7/df/452648f157f00c4876e60d60a5f6ee0da1bdc0653d1a8f85478dce607235/zope.pagetemplate-5.1.tar.gz", hash = "sha256:99e14fa001f652320cae0a3deb2bd97088eb6302d58e4c71e1d633b88cca5eae", size = 42653 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a3/fb/b2e7ef002bb38c88e2ea8247415554c8f6f3661fcdeee0fbbe4eeeebea4c/zope.pagetemplate-5.1-py3-none-any.whl", hash = "sha256:c2a49be21c13c8053ac83f93a4f6faae7e2799f165db3e65cd3a7d16a3cca8b1", size = 44995 },
+]
+
+[[package]]
+name = "zope-processlifetime"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5e/e0/8e863d96442e642f0b8d55a5c370cf5b2db907799895b5b7d8aa041c14fe/zope.processlifetime-3.0.tar.gz", hash = "sha256:c049c195c6c23c0cecf9675ee1c6c02028e10cebf37c459c0aa1834d38bd8c2e", size = 13586 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/6c/5b/f5f4e8363b308b463667d42fe7ff3a01dcd74eb21330e6b5cb37c346d565/zope.processlifetime-3.0-py3-none-any.whl", hash = "sha256:ca4e6c5ffbf879fa3b5575246010459c4fddb7fe513cbf9c92fdb7078eb84f6a", size = 5867 },
+]
+
+[[package]]
+name = "zope-proxy"
+version = "6.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/5c/1c/d051c6a2968a189787c7ed8f789201dd7ee0f40e5c1553ea513bdbd21dcf/zope_proxy-6.1.tar.gz", hash = "sha256:9b70bf787fcbd3ecb86ba886d71e5cd857da0d6dbe2fcf2b6c24774f24747e2e", size = 43823 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/62/fb/de3be3871ce25776f46f73c3c1e3a19cd4d418b0e167c475486f728cc180/zope.proxy-6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:205d6addd0a19ac2febc0b0bf5dabc5b9ae7db385a6a84dddaf3237d113ee01f", size = 39326 },
+ { url = "https://files.pythonhosted.org/packages/8f/b7/2bf9814ff968d77244cf3d84e4f1dda07901a927a01cb13cf61479112e31/zope.proxy-6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ea7b1b14c31d28de0c3dbbb6672e36dea62828866831bd8a9736171b1d82465", size = 39762 },
+ { url = "https://files.pythonhosted.org/packages/e9/fe/de76477112bcf671f21fb39fbbe5613e2207f679cad0c8e79323d62f6797/zope.proxy-6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51a6be9875dd4bd3945da4338120baed733610acb961c77f3bdfec9ba1be208e", size = 72743 },
+ { url = "https://files.pythonhosted.org/packages/7f/44/9cb3b1148736459b610048dc1f4b72d8d8c3b866e920ee1fc0ce81d28187/zope.proxy-6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9799b3016982a32dc9f9e4f42e443a52c88b3f601a50d21951d0ef450999b85d", size = 67966 },
+ { url = "https://files.pythonhosted.org/packages/63/7c/0b22b3aca302f7e22a108be20923745d4b2a3b0a149b64cf9e5ac67a53f2/zope.proxy-6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed87d7c006d635e4f92c94dbb8ad6082b1fe828dfa76ed3c78610bc84cefdeb7", size = 73534 },
+ { url = "https://files.pythonhosted.org/packages/48/99/3ca142e945075e082a17278c3cc47822cc9b8285bbdb0943e5d8c81fdf20/zope.proxy-6.1-cp312-cp312-win_amd64.whl", hash = "sha256:60497b06f9e249b3c21b09ce1775b3d71a74a37cea44207cd997317a77fc5918", size = 40813 },
+ { url = "https://files.pythonhosted.org/packages/49/62/3f9cbf9bcb58b5e330fc5b37d42c2a9fbcbfe2feecde7bf58966b08e8f46/zope.proxy-6.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:cda5526ebea4aced070bfa0ce73e7b3a2a2250988a5b12b1593fe510dd3338db", size = 39325 },
+ { url = "https://files.pythonhosted.org/packages/3d/f2/ade1536faac8f08fb237d7c53865c3b1f835539ff80e08d955a233f635c6/zope.proxy-6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6f7208e4630003bf77abd64f54d0e98767fa146f2930b7bfb4ba12e23bbfb006", size = 39762 },
+ { url = "https://files.pythonhosted.org/packages/1e/91/1f30f4635f7aeb31134bc3118e1fca20c7ddc5d3e125eb269f3801cbf0ff/zope.proxy-6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07c43ae0180ba4dc6fa41cc9e306d5e5c063014fb8d4e8614b49f8f934d42eb9", size = 72756 },
+ { url = "https://files.pythonhosted.org/packages/45/a3/cab9b3e54d6bc06711d7779b50e14b0805618445e0c3ee8e82cf6a0ad01c/zope.proxy-6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71d9b46af85bca3ceb1fa60b95591cce50538265b73f0eefb735bd366199ebeb", size = 67956 },
+ { url = "https://files.pythonhosted.org/packages/05/b4/56ba31881edb1858b5c009973ea2362041bd36179a9f6496446c62eeab7d/zope.proxy-6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fd5b73c60cd64e9225d5dd810742e467c8086b7615d29849ac53a98ab059267", size = 73510 },
+ { url = "https://files.pythonhosted.org/packages/cd/da/2e120d9dfc21c135d749390e6f16c18ced83e803b55412ef23b28c337af1/zope.proxy-6.1-cp313-cp313-win_amd64.whl", hash = "sha256:17fa348ec0ac9daafb9a0380e067ed1e8fc1ddcaefc31b094e255544319b8609", size = 40822 },
+]
+
+[[package]]
+name = "zope-ptresource"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-browserresource" },
+ { name = "zope-interface" },
+ { name = "zope-pagetemplate" },
+ { name = "zope-publisher" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/da/ac/eda7b3b74726d82ebbe712a3753bc36151f289f8271711c9c952c4c24910/zope.ptresource-5.0.tar.gz", hash = "sha256:fe1bfcba80cefb97bf1551409b7e24a7d30ba4941cdd6a95983d52f1f25e4b1a", size = 8785 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b0/4c/88f4472d3cf2224d7877ba894987f23f7d23f5633deb9d5f9cac3c418a69/zope.ptresource-5.0-py3-none-any.whl", hash = "sha256:109208d35cb66c1b81d81c8b520390a2f17559166c5477cb4adde26fb346d2d6", size = 7617 },
+]
+
+[[package]]
+name = "zope-publisher"
+version = "7.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "multipart" },
+ { name = "setuptools" },
+ { name = "zope-browser" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-contenttype" },
+ { name = "zope-event" },
+ { name = "zope-exceptions" },
+ { name = "zope-i18n" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-proxy" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/6e/68/db4fb965921b4f98859f36ee3c0f18f069c169a745bae3a7eaa3bbcc41b1/zope_publisher-7.3.tar.gz", hash = "sha256:74c95eada138d729b16b52fdcbac2eb8718bd6462e1782901b01bcbf6a44ddcd", size = 111141 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/21/aa/7c0ab8354204b8236591e3a2fce88359e225cbb4815dbca114d39bb8944e/zope.publisher-7.3-py3-none-any.whl", hash = "sha256:da1eb6a5e0a3a6438a3ea77605220b4e32154449908206096e8a0e2d2427e3e8", size = 119839 },
+]
+
+[[package]]
+name = "zope-pytestlayer"
+version = "8.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pytest" },
+ { name = "setuptools" },
+ { name = "zope-dottedname" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/cb/99/ecc0b4aeb9072edde6e2ccf5c1b9498d16e86d1e456191c9bd828598a1d0/zope.pytestlayer-8.2.tar.gz", hash = "sha256:15b5a862f595cc3844dec506a52968c60b572b3d0cfa320d7caf9bad97d5eb54", size = 25506 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f4/94/51b0032b171e82e3d1019a95f32a97e7381a3d5b0aafc85e915ec7413413/zope.pytestlayer-8.2-py3-none-any.whl", hash = "sha256:c0e6e26811fd909fa1fa9dddbae0842663b6fb1a4dd6b814abac4639b1cde7c1", size = 37661 },
+]
+
+[[package]]
+name = "zope-ramcache"
+version = "3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "persistent" },
+ { name = "setuptools" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/1a/19/700ca14de1855da4bff52630012d168799a2322ea472f8f273e9e56ff547/zope.ramcache-3.0.tar.gz", hash = "sha256:e2693786372a9fe65e4e541eb003449cb3f745a2dad7cf586769f3e87ba52b44", size = 14124 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cf/dd/f0a94778fac803dc7c3fb061990ab4d2904cd83ab2485cf23e42861c206e/zope.ramcache-3.0-py3-none-any.whl", hash = "sha256:6777bc8b28ad57a4ac61a1faf3fc6e29b6663a9988dc1168e965df4144f05b6f", size = 14684 },
+]
+
+[[package]]
+name = "zope-schema"
+version = "7.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/82/67/91585500260386df145b78532de588b41470d416bc6fa1cdc1b0f7a34e68/zope.schema-7.0.1.tar.gz", hash = "sha256:ead4dbcb03354d4e410c9a3b904451eb44d90254751b1cbdedf4a61aede9fbb9", size = 108737 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1d/97/517e3f5f4258bcc6491c806474a26e1a799bb99ec44ed95d22010caabc25/zope.schema-7.0.1-py3-none-any.whl", hash = "sha256:cf006c678793b00e0075ad54d55281c8785ea21e5bc1f5ec0584787719c2aab2", size = 85870 },
+]
+
+[[package]]
+name = "zope-security"
+version = "7.3"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-component" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-proxy" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/aa/08/d1696704a8466e94495051dc82af8e30a6e80b2a5a24646683bf6008097f/zope_security-7.3.tar.gz", hash = "sha256:5db5f79195321f2450ba49b3e1e47ba54364f966fdfc6d39df723043fe6c5549", size = 145814 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3f/10/128bdd43383506f31a7db28fa8b02850c93c6f6317859454e512a6091325/zope.security-7.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:de0a40b75dd11df3a7fdb15843a678c2f2027a1e609ee97d45952d6c5dd344f9", size = 123631 },
+ { url = "https://files.pythonhosted.org/packages/e3/60/262c04b1d9dc3a2bf5d06fbc94fd2ad0d49fb84d52f75e42fad212ef2b00/zope.security-7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb79f3cb32036cf378b7f7f2eb009ca1d212e3bc487380d7e3894a97954363ad", size = 123772 },
+ { url = "https://files.pythonhosted.org/packages/dc/36/326754812d882469b12e7089824b9dc8d66d917072f9339be0e0d93585e6/zope.security-7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cade045c47380bee6611515cee3f88aeb6159a0c2bd68725ec1ca58dce90585", size = 186822 },
+ { url = "https://files.pythonhosted.org/packages/af/93/59aa73ee4f6f49d8f41628b3b79f421c94daa29763086702bc64f0130e4f/zope.security-7.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a0421fecefb3b14762d329b0e63f19528672bc5ce240f1c2d0f3c0f2bf1e7e0", size = 179997 },
+ { url = "https://files.pythonhosted.org/packages/3d/a1/45d8b375b6a534c5bc5e23b76a4b52a1d8387d20367c850dac66400c8e77/zope.security-7.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7e8cb657ea45caa22c752407eb3c947d7fcb029bbf706f727400f786008972f", size = 188080 },
+ { url = "https://files.pythonhosted.org/packages/4a/cf/44749513b3da0adc2246c003fc242a71854a968679c7b52ee7b2443f63d1/zope.security-7.3-cp312-cp312-win_amd64.whl", hash = "sha256:436db149fda755e24c60db54df3735d4d0a5f70deb3e847d3e262fe00b08a9ca", size = 128013 },
+ { url = "https://files.pythonhosted.org/packages/f3/59/9a7f1cb96c5bb117ff9c7b4b631bd872abdb1419e42d6601510b6ca5b861/zope.security-7.3-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:7f687e114debee04b60042c8ca0c02ea036738819616fe35d52203f987962ea7", size = 123636 },
+ { url = "https://files.pythonhosted.org/packages/56/7d/a271959598815ed651af490ae1471a238a3c8ad74c2eccf596f2e574ae21/zope.security-7.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0a3b81c4a89e9ab713aaf75d587b12292129c72b8da7dc022c8cdc726aa001b5", size = 123775 },
+ { url = "https://files.pythonhosted.org/packages/2a/e9/8e166a3d83206dea1ad3b3cefed7dabb9dba873eb0bfa4b8df337ee87279/zope.security-7.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e722e08ab9f2ce211c47f5a89f3b3052f970d0fea59dcf4990891b896f0e1133", size = 186781 },
+ { url = "https://files.pythonhosted.org/packages/a2/db/b0a64540c8c351449c65803f7b3fbca77a1636fd676da13a03e2027dc1e5/zope.security-7.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5d6dbd1328d8f678a1282b976083504ceb2cbfb4e4ed6c2d7200adf285bd79c7", size = 179945 },
+ { url = "https://files.pythonhosted.org/packages/44/97/64bc28636810e8d14a94160e7bf14b6d687ea0b0a7db9e2d06680b848362/zope.security-7.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90128acf1435fd9353f4485bf2fdaf582ccb6a1ee1ce0353ead370a892e5b9b1", size = 188001 },
+ { url = "https://files.pythonhosted.org/packages/3d/db/ecfc88c439b351b02c2836e64853a605477671a6d0c62e936530d6b3880a/zope.security-7.3-cp313-cp313-win_amd64.whl", hash = "sha256:3b3779d1e1c9728aa389bbab5c5a35cf257b27c7dbfb9138a630e5c6529851cb", size = 128033 },
+]
+
+[[package]]
+name = "zope-sendmail"
+version = "6.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pywin32", marker = "sys_platform == 'win32'" },
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/bd/81/1023bc85ff32cf57a517a265a9963a906f47a7322b4b6442294a817afbc6/zope.sendmail-6.2.tar.gz", hash = "sha256:bc7626be0b05168ccbfa4e7a6548775953bed80025e543fab3115094f30d3b45", size = 50948 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/11/10/34bd8adcf944fbb591bb651facf1ef4a1ae9c2e3a12224096821769b4c4f/zope.sendmail-6.2-py3-none-any.whl", hash = "sha256:75618a369ec7c13a9b446fdbf3df46788fb9651bd5f1fea9cc8403307f41a416", size = 47063 },
+]
+
+[[package]]
+name = "zope-sequencesort"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/fc/57/ec0f465031038a79567b6ce3e271eea88586bdc5d87e5aad697b00010b98/zope.sequencesort-5.0.tar.gz", hash = "sha256:80d1ecaa5a8576e0f92533884cacc9aa9867ee0fc427ad70898ce1491972ef1c", size = 18540 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/60/8f/e0bdfdd1a0315469e57c23661f37dcb679800b24ece64f6bc2a9d7dc8755/zope.sequencesort-5.0-py3-none-any.whl", hash = "sha256:ae73e14733d80d93702aa210148449285e7a3171762bf50872cb1ab01dc5ec00", size = 11216 },
+]
+
+[[package]]
+name = "zope-site"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-annotation" },
+ { name = "zope-component" },
+ { name = "zope-container" },
+ { name = "zope-deprecation" },
+ { name = "zope-event" },
+ { name = "zope-interface" },
+ { name = "zope-lifecycleevent" },
+ { name = "zope-location" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/d3/4d/da5af540dfd5cd105979ce9232a84eacecd8a335535bb4d09504e286cb28/zope.site-5.0.tar.gz", hash = "sha256:58f8135f40a7b22ef0d6e4dbd9324f414bc17f33b2482dfbe34f18e7ef05e21e", size = 37268 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/af/a7/728eb22ce8e15f4a70cba9a14bd7b0cae4979fe6faf710bc790a357e805a/zope.site-5.0-py3-none-any.whl", hash = "sha256:dc42baddced99bf65f4f458ab52d2b2ec05ff04387f81cbe82326c8fb7878c40", size = 30280 },
+]
+
+[[package]]
+name = "zope-size"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/cd/39/0f00742892eeb81e3fc9f8d73db4804d6c73ba4ebc0fbc376b855d28f39d/zope.size-5.0.tar.gz", hash = "sha256:b15453e34f816ff5459ad83cd935029aa581c6a453463e03c5e2d97bd20a432a", size = 14737 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/36/18/9d02077feb06605d24cb6ed1604b0313f9619700781c3bb546d72afaf221/zope.size-5.0-py3-none-any.whl", hash = "sha256:2d4b3d6de6c51ad003ee16631f8bf423f4b3f8ecaf48ac46ca39f3f4c22319ba", size = 7926 },
+]
+
+[[package]]
+name = "zope-structuredtext"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/65/91/d4f9c0f809f373fcc4cb9adbacd55649d2a0bb774c02f30a6c7cc499f013/zope.structuredtext-5.0.tar.gz", hash = "sha256:c627f997704edbc6aec9c1e88d7dacd48acc7eeeba3324bbf565cdbb1f3db682", size = 73749 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/33/01/6dd11051048313f8a0c8e418d7790bb1af43488900cb82b104bca7a63ae8/zope.structuredtext-5.0-py3-none-any.whl", hash = "sha256:561c86389d122eb97a04832a062d53308b614c265435e00eef08b93e00576169", size = 92490 },
+]
+
+[[package]]
+name = "zope-tal"
+version = "5.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f5/c8/dc51eb13a13e8e9d965bda205a50c589f12d33f3892f776f49b94a2a07fe/zope.tal-5.0.1.tar.gz", hash = "sha256:3440e3b7bc8ea6395628b0cf15f2aa74027b8a0a742032740eec98881e14d7a7", size = 91313 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/95/11/7347999cf60f7a40e0062ea38955ab004c973fe58a8ad42099e4ac553bdc/zope.tal-5.0.1-py3-none-any.whl", hash = "sha256:a25020172500e95c293be0601200521596c8bee30f6cf4da8e224a004baac319", size = 135895 },
+]
+
+[[package]]
+name = "zope-tales"
+version = "6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/c7/92/4082559b9c3c888c8ad8bf2097ef029c92c9b081f804ccb98f413a79809e/zope.tales-6.0.tar.gz", hash = "sha256:47e76ce36cfdb7d4d0e8c840913bd1deadf3b7a12b61d7351133cf95224266b0", size = 31245 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a1/43/6080465e19e35dbee4c8512694858210e872181f2f706e53010840779669/zope.tales-6.0-py3-none-any.whl", hash = "sha256:72653404548da757c24f67b264024ec79f8a93d4e2d76f71b8337f594b8a536f", size = 30153 },
+]
+
+[[package]]
+name = "zope-testbrowser"
+version = "7.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "beautifulsoup4" },
+ { name = "legacy-cgi", marker = "python_full_version >= '3.13'" },
+ { name = "pytz" },
+ { name = "setuptools" },
+ { name = "soupsieve" },
+ { name = "webtest" },
+ { name = "wsgiproxy2" },
+ { name = "zope-cachedescriptors" },
+ { name = "zope-interface" },
+ { name = "zope-schema" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/46/5f/db2128c4dc3cc3077d2652ba2232685fb2f8c0ee6bd970b2dbf165ef7a54/zope.testbrowser-7.0.tar.gz", hash = "sha256:5936d2a0d77d8781d001358fd0b11461285b02dc6e3b324b84c1ed9326b1ff3f", size = 85418 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/84/77/7e1cd9022a41bb3294b735f460b8a7ec59c3d0ba0e8b1f84d8a3674615e0/zope.testbrowser-7.0-py3-none-any.whl", hash = "sha256:75fa5f63f69fe4ebd6e6a7cebf2dc7da61a4c2a248f69b0b171d218af51a860e", size = 63464 },
+]
+
+[[package]]
+name = "zope-testing"
+version = "5.0.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/1c/45/a22985a9a5bb886ae0665f04c1ffe985d9558c3e9881fde808fc9dc0a6f9/zope.testing-5.0.1.tar.gz", hash = "sha256:e87cd0d8d666573cdaf133816ab7b9beec801a64a86595c19cb5fe992ef3d649", size = 41745 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/82/eb/d09f00ea8c73cfbf8d0d72109fca19808c283b1d0da701b1be9c40b99e42/zope.testing-5.0.1-py3-none-any.whl", hash = "sha256:b3c8fc322418ab561d56d1cdad92812a2b2d79d366e7bb9a31437c72ad4b4dad", size = 37191 },
+]
+
+[[package]]
+name = "zope-testrunner"
+version = "7.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-exceptions" },
+ { name = "zope-interface" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/85/80/a01c595683406b31b33a136907d252de7b4a56ee5553990aa363866bbe80/zope_testrunner-7.2.tar.gz", hash = "sha256:d4fae0ba3b0e287a60591a9e350ddf7cb3150b73951eecfa835f80d0abe61280", size = 159809 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/af/b2/415a8ec88db91f2836045fc6048ff1262171981002af3d3c0ae3211c9ad2/zope.testrunner-7.2-py3-none-any.whl", hash = "sha256:fec07f0fcabf9c4c9c82fc7a596bd2db1d44c2e4476f56c4810e66e0d74c4005", size = 231066 },
+]
+
+[[package]]
+name = "zope-traversing"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "transaction" },
+ { name = "zope-component" },
+ { name = "zope-i18n" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-proxy" },
+ { name = "zope-publisher" },
+ { name = "zope-security" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/ba/eb/4fb91cde93ef76be16b958a8b48045892c94c3fca0834d29656f174ef70a/zope.traversing-5.0.tar.gz", hash = "sha256:f11c4622526cd328f3ab5cf6cc34c0226dc2137d26af9c11b34c507da11c44f5", size = 42671 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d9/47/34fdb495867649747ddea10d7c9e83f7a1d8bcecdf86eeb4d46ed123faed/zope.traversing-5.0-py3-none-any.whl", hash = "sha256:1c26c8f0067821e2ad198553b3a548d7edb352e0969d4f283e635e67d4c2874e", size = 47610 },
+]
+
+[[package]]
+name = "zope-viewlet"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "setuptools" },
+ { name = "zope-browserpage" },
+ { name = "zope-component" },
+ { name = "zope-configuration" },
+ { name = "zope-contentprovider" },
+ { name = "zope-event" },
+ { name = "zope-i18nmessageid" },
+ { name = "zope-interface" },
+ { name = "zope-location" },
+ { name = "zope-publisher" },
+ { name = "zope-schema" },
+ { name = "zope-security" },
+ { name = "zope-traversing" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/22/60/a924e90e0ba976597f9c817900e93a59b6fa02ad3d49dd88a76d3901509f/zope.viewlet-5.0.tar.gz", hash = "sha256:dba387c407c918244030c1a771773fec8e4167b0464e2f82474f489b8b306300", size = 33743 }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fe/bc/5dccf8db564dce1cb621ddce4687ea380f75e045bb92494ff84cd5aa3cae/zope.viewlet-5.0-py3-none-any.whl", hash = "sha256:ba16d475bdeb5532f39de5755de8a5a06ed0d74a63af9d052286b658e6795eba", size = 33022 },
+]
diff --git a/backend/version.txt b/backend/version.txt
index dfda3e0..f3b5af3 100644
--- a/backend/version.txt
+++ b/backend/version.txt
@@ -1 +1 @@
-6.1.0
+6.1.1
diff --git a/devops/varnish/Dockerfile b/devops/varnish/Dockerfile
index 0e24a59..427105a 100644
--- a/devops/varnish/Dockerfile
+++ b/devops/varnish/Dockerfile
@@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1
-FROM varnish:7.4
+FROM varnish:7.6
LABEL maintainer="PloneGov-BR " \
- org.label-schema.name="pythonbrasil/pybr25-site-varnish" \
+ org.label-schema.name="pybr25-site-varnish" \
org.label-schema.description="PythonBrasil 2025 Varnish image." \
org.label-schema.vendor="PloneGov-BR"
diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml
new file mode 100644
index 0000000..eb87174
--- /dev/null
+++ b/docker-compose-dev.yml
@@ -0,0 +1,139 @@
+---
+name: pybr25-site-local-dev
+
+services:
+ traefik:
+ image: traefik:v2.11
+
+ ports:
+ - 80:80
+
+ labels:
+ - traefik.enable=true
+ - traefik.constraint-label=public
+ - traefik.http.routers.traefik-public-http.rule=Host(`traefik.${HOSTNAME:-pybr25-site.localhost}`)
+ - traefik.http.routers.traefik-public-http.entrypoints=http
+ - traefik.http.routers.traefik-public-http.service=api@internal
+ - traefik.http.services.traefik-public.loadbalancer.server.port=8000
+
+ # GENERIC MIDDLEWARES
+ - traefik.http.middlewares.gzip.compress=true
+ - traefik.http.middlewares.gzip.compress.excludedcontenttypes=image/png, image/jpeg, font/woff2
+
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+
+ command:
+ - --providers.docker
+ - --providers.docker.constraints=Label(`traefik.constraint-label`, `public`)
+ - --providers.docker.exposedbydefault=false
+ - --entrypoints.http.address=:80
+ - --accesslog
+ - --log
+ - --api
+ purger:
+ image: ghcr.io/kitconcept/cluster-purger:latest
+ platform: linux/amd64
+ environment:
+ PURGER_SERVICE_NAME: varnish
+ PURGER_SERVICE_PORT: 80
+ PURGER_MODE: "compose"
+ PURGER_PUBLIC_SITES: "['${HOSTNAME:-pybr25-site.localhost}']"
+
+ varnish:
+ build:
+ context: devops/varnish
+ labels:
+ - traefik.enable=true
+ - traefik.constraint-label=public
+ # SERVICE
+ - traefik.http.services.svc-varnish.loadbalancer.server.port=80
+ depends_on:
+ - backend
+ frontend:
+ build:
+ context: ./frontend
+ args:
+ - VOLTO_VERSION=${VOLTO_VERSION}
+ environment:
+ RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone
+ depends_on:
+ - backend
+ labels:
+ - traefik.enable=true
+ - traefik.constraint-label=public
+ # Service
+ - traefik.http.services.svc-frontend.loadbalancer.server.port=3000
+ # Routers
+ ## /
+ ### Router: Varnish Public
+ - traefik.http.routers.rt-frontend-public.rule=Host(`${HOSTNAME:-pybr25-site.localhost}`)
+ - traefik.http.routers.rt-frontend-public.entrypoints=http
+ - traefik.http.routers.rt-frontend-public.service=svc-varnish
+ - traefik.http.routers.rt-frontend-public.middlewares=gzip
+ ### Router: Internal
+ - traefik.http.routers.rt-frontend-internal.rule=Host(`${HOSTNAME:-pybr25-site.localhost}`) && Headers(`X-Varnish-Routed`, `1`)
+ - traefik.http.routers.rt-frontend-internal.entrypoints=http
+ - traefik.http.routers.rt-frontend-internal.service=svc-frontend
+
+ backend:
+ build:
+ context: ./backend
+ args:
+ - PLONE_VERSION=${PLONE_VERSION}
+ environment:
+ RELSTORAGE_DSN: "dbname='${DB_NAME:-plone}' user='${DB_NAME:-plone}' host='${DB_HOST:-db}' password='${DB_PASSWORD:-MCfLPlcVlekH}' port='${DB_PORT:-5432}'"
+ depends_on:
+ - db
+ labels:
+ - traefik.enable=true
+ - traefik.constraint-label=public
+ # Services
+ - traefik.http.services.svc-backend.loadbalancer.server.port=8080
+
+ # Middlewares
+ ## VHM rewrite /++api++/
+ - "traefik.http.middlewares.mw-backend-vhm-api.replacepathregex.regex=^/\\+\\+api\\+\\+($$|/.*)"
+ - "traefik.http.middlewares.mw-backend-vhm-api.replacepathregex.replacement=/VirtualHostBase/http/${HOSTNAME:-pybr25-site.localhost}/Plone/++api++/VirtualHostRoot$$1"
+
+ ## VHM rewrite /ClassicUI/
+ - "traefik.http.middlewares.mw-backend-vhm-classic.replacepathregex.regex=^/ClassicUI($$|/.*)"
+ - "traefik.http.middlewares.mw-backend-vhm-classic.replacepathregex.replacement=/VirtualHostBase/http/${HOSTNAME:-pybr25-site.localhost}/Plone/VirtualHostRoot/_vh_ClassicUI$$1"
+
+ ## Basic Authentication
+ ### Note: all dollar signs in the hash need to be doubled for escaping.
+ ### To create user:password pair, it's possible to use this command:
+ ### echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
+ ### Defaults to admin:admin
+ - traefik.http.middlewares.mw-backend-auth.basicauth.headerField=X-Auth-ClassicUI
+ - traefik.http.middlewares.mw-backend-auth.basicauth.users=admin:$$apr1$$uZPT5Fgu$$AmlIdamxT5ipBvPlsdfD70
+ # Routers
+ ## /++api++/
+ ### Router: Varnish Public
+ - traefik.http.routers.rt-backend-api-public.rule=Host(`${HOSTNAME:-pybr25-site.localhost}`) && PathPrefix(`/++api++`)
+ - traefik.http.routers.rt-backend-api-public.entrypoints=http
+ - traefik.http.routers.rt-backend-api-public.service=svc-varnish
+ - traefik.http.routers.rt-backend-api-public.middlewares=gzip
+
+ ### Router: Internal
+ - traefik.http.routers.rt-backend-api-internal.rule=Host(`${HOSTNAME:-pybr25-site.localhost}`) && PathPrefix(`/++api++`) && Headers(`X-Varnish-Routed`, `1`)
+ - traefik.http.routers.rt-backend-api-internal.entrypoints=http
+ - traefik.http.routers.rt-backend-api-internal.service=svc-backend
+ - traefik.http.routers.rt-backend-api-internal.middlewares=gzip,mw-backend-vhm-api
+ ## /ClassicUI
+ - traefik.http.routers.rt-backend-classic.rule=Host(`${HOSTNAME:-pybr25-site.localhost}`) && PathPrefix(`/ClassicUI`)
+ - traefik.http.routers.rt-backend-classic.entrypoints=http
+ - traefik.http.routers.rt-backend-classic.service=svc-backend
+ - traefik.http.routers.rt-backend-classic.middlewares=gzip,mw-backend-auth,mw-backend-vhm-classic
+
+ db:
+ image: postgres:14.15
+ environment:
+ POSTGRES_USER: plone
+ POSTGRES_PASSWORD: MCfLPlcVlekH
+ POSTGRES_DB: plone
+ volumes:
+ - vol-site-data:/var/lib/postgresql/data
+
+volumes:
+ vol-site-data: {}
diff --git a/docker-compose.yml b/docker-compose.yml
index 658ced9..fa44b91 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,9 +1,9 @@
---
-name: 2025-pythonbrasil-org-br
+name: pybr25-site
services:
traefik:
- image: traefik:v2.10
+ image: traefik:v2.11
ports:
- 80:80
@@ -11,7 +11,7 @@ services:
labels:
- traefik.enable=true
- traefik.constraint-label=public
- - traefik.http.routers.traefik-public-http.rule=Host(`traefik.2025.pythonbrasil.org.br.localhost`)
+ - traefik.http.routers.traefik-public-http.rule=Host(`traefik.pythonbrasil.localhost`)
- traefik.http.routers.traefik-public-http.entrypoints=http
- traefik.http.routers.traefik-public-http.service=api@internal
- traefik.http.services.traefik-public.loadbalancer.server.port=8000
@@ -31,30 +31,10 @@ services:
- --accesslog
- --log
- --api
- purger:
- image: ghcr.io/kitconcept/cluster-purger:latest
- platform: linux/amd64
- environment:
- PURGER_SERVICE_NAME: varnish
- PURGER_SERVICE_PORT: 80
- PURGER_MODE: "compose"
- PURGER_PUBLIC_SITES: "['2025.pythonbrasil.org.br.localhost']"
- varnish:
- build:
- context: devops/varnish
- labels:
- - traefik.enable=true
- - traefik.constraint-label=public
- # SERVICE
- - traefik.http.services.svc-varnish.loadbalancer.server.port=80
- depends_on:
- - backend
frontend:
- build:
- context: ./frontend
- args:
- - VOLTO_VERSION=${VOLTO_VERSION}
+ image: ghcr.io/pythonbrasil/pybr25-site-frontend:${IMAGE_VERSION:-20250212.1}
+ platform: linux/amd64
environment:
RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone
depends_on:
@@ -67,22 +47,16 @@ services:
# Routers
## /
### Router: Varnish Public
- - traefik.http.routers.rt-frontend-public.rule=Host(`2025.pythonbrasil.org.br.localhost`)
+ - traefik.http.routers.rt-frontend-public.rule=Host(`pythonbrasil.localhost`)
- traefik.http.routers.rt-frontend-public.entrypoints=http
- - traefik.http.routers.rt-frontend-public.service=svc-varnish
+ - traefik.http.routers.rt-frontend-public.service=svc-frontend
- traefik.http.routers.rt-frontend-public.middlewares=gzip
- ### Router: Internal
- - traefik.http.routers.rt-frontend-internal.rule=Host(`2025.pythonbrasil.org.br.localhost`) && Headers(`X-Varnish-Routed`, `1`)
- - traefik.http.routers.rt-frontend-internal.entrypoints=http
- - traefik.http.routers.rt-frontend-internal.service=svc-frontend
backend:
- build:
- context: ./backend
- args:
- - PLONE_VERSION=${PLONE_VERSION}
+ image: ghcr.io/pythonbrasil/pybr25-site-backend:${IMAGE_VERSION:-20250212.1}
+ platform: linux/amd64
environment:
- RELSTORAGE_DSN: "dbname='${DB_NAME:-plone}' user='${DB_NAME:-plone}' host='${DB_HOST:-db}' password='${DB_PASSWORD:-NBLEJnJWxgYN}' port='${DB_PORT:-5432}'"
+ RELSTORAGE_DSN: "dbname='${DB_NAME:-plone}' user='${DB_NAME:-plone}' host='${DB_HOST:-db}' password='${DB_PASSWORD:-MCfLPlcVlekH}' port='${DB_PORT:-5432}'"
depends_on:
- db
labels:
@@ -94,42 +68,38 @@ services:
# Middlewares
## VHM rewrite /++api++/
- "traefik.http.middlewares.mw-backend-vhm-api.replacepathregex.regex=^/\\+\\+api\\+\\+($$|/.*)"
- - "traefik.http.middlewares.mw-backend-vhm-api.replacepathregex.replacement=/VirtualHostBase/http/2025.pythonbrasil.org.br.localhost/Plone/++api++/VirtualHostRoot$$1"
+ - "traefik.http.middlewares.mw-backend-vhm-api.replacepathregex.replacement=/VirtualHostBase/http/pythonbrasil.localhost/Plone/++api++/VirtualHostRoot$$1"
## VHM rewrite /ClassicUI/
- "traefik.http.middlewares.mw-backend-vhm-classic.replacepathregex.regex=^/ClassicUI($$|/.*)"
- - "traefik.http.middlewares.mw-backend-vhm-classic.replacepathregex.replacement=/VirtualHostBase/http/2025.pythonbrasil.org.br.localhost/Plone/VirtualHostRoot/_vh_ClassicUI$$1"
+ - "traefik.http.middlewares.mw-backend-vhm-classic.replacepathregex.replacement=/VirtualHostBase/http/pythonbrasil.localhost/Plone/VirtualHostRoot/_vh_ClassicUI$$1"
## Basic Authentication
### Note: all dollar signs in the hash need to be doubled for escaping.
### To create user:password pair, it's possible to use this command:
### echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
### Defaults to admin:admin
+ - traefik.http.middlewares.mw-backend-auth.basicauth.headerField=X-Auth-ClassicUI
- traefik.http.middlewares.mw-backend-auth.basicauth.users=admin:$$apr1$$uZPT5Fgu$$AmlIdamxT5ipBvPlsdfD70
# Routers
## /++api++/
### Router: Varnish Public
- - traefik.http.routers.rt-backend-api-public.rule=Host(`2025.pythonbrasil.org.br.localhost`) && PathPrefix(`/++api++`)
+ - traefik.http.routers.rt-backend-api-public.rule=Host(`pythonbrasil.localhost`) && PathPrefix(`/++api++`)
- traefik.http.routers.rt-backend-api-public.entrypoints=http
- - traefik.http.routers.rt-backend-api-public.service=svc-varnish
- - traefik.http.routers.rt-backend-api-public.middlewares=gzip
+ - traefik.http.routers.rt-backend-api-public.service=svc-backend
+ - traefik.http.routers.rt-backend-api-public.middlewares=gzip,mw-backend-vhm-api
- ### Router: Internal
- - traefik.http.routers.rt-backend-api-internal.rule=Host(`2025.pythonbrasil.org.br.localhost`) && PathPrefix(`/++api++`) && Headers(`X-Varnish-Routed`, `1`)
- - traefik.http.routers.rt-backend-api-internal.entrypoints=http
- - traefik.http.routers.rt-backend-api-internal.service=svc-backend
- - traefik.http.routers.rt-backend-api-internal.middlewares=gzip,mw-backend-vhm-api
## /ClassicUI
- - traefik.http.routers.rt-backend-classic.rule=Host(`2025.pythonbrasil.org.br.localhost`) && PathPrefix(`/ClassicUI`)
+ - traefik.http.routers.rt-backend-classic.rule=Host(`pythonbrasil.localhost`) && PathPrefix(`/ClassicUI`)
- traefik.http.routers.rt-backend-classic.entrypoints=http
- traefik.http.routers.rt-backend-classic.service=svc-backend
- traefik.http.routers.rt-backend-classic.middlewares=gzip,mw-backend-auth,mw-backend-vhm-classic
db:
- image: postgres:14
+ image: postgres:14.15
environment:
POSTGRES_USER: plone
- POSTGRES_PASSWORD: NBLEJnJWxgYN
+ POSTGRES_PASSWORD: MCfLPlcVlekH
POSTGRES_DB: plone
volumes:
- vol-site-data:/var/lib/postgresql/data
diff --git a/frontend/.dockerignore b/frontend/.dockerignore
new file mode 100644
index 0000000..71a9d07
--- /dev/null
+++ b/frontend/.dockerignore
@@ -0,0 +1,6 @@
+*.log
+build
+cache
+cypress
+Dockerfile
+node_modules
diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js
index 63bc293..8cfa71d 100644
--- a/frontend/.eslintrc.js
+++ b/frontend/.eslintrc.js
@@ -29,7 +29,7 @@ module.exports = {
['@plone/volto-slate', `${coreLocation}/packages/volto-slate/src`],
['@plone/registry', `${coreLocation}/packages/registry/src`],
[
- 'volto-pythonbrasil-site',
+ '@plonegovbr/volto-pythonbrasil-site',
'./packages/volto-pythonbrasil-site/src',
],
...addonAliases,
diff --git a/frontend/.gitignore b/frontend/.gitignore
index cdcd937..2afc709 100644
--- a/frontend/.gitignore
+++ b/frontend/.gitignore
@@ -6,7 +6,7 @@ acceptance/cypress/videos/
acceptance/node_modules
.storybook-build
build
-core
+/core
node_modules
results
yarn.lock
diff --git a/frontend/.pre-commit-config.yaml b/frontend/.pre-commit-config.yaml
deleted file mode 100644
index 3c7d331..0000000
--- a/frontend/.pre-commit-config.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-repos:
- - repo: local
- hooks:
- - id: prettier
- name: prettier
- entry: pnpm exec prettier --write
- language: system
- files: '^packages/.*/src/.*/?.*.(js|jsx|ts|tsx)$'
- types: [file]
- - id: eslint
- name: eslint
- entry: bash -c "VOLTOCONFIG=$(pwd)/volto.config.js pnpm exec eslint --max-warnings=0 --fix"
- language: system
- files: '^packages/.*/src/.*/?.*.(js|jsx|ts|tsx)$'
- types: [file]
- - id: stylelint
- name: stylelint
- entry: pnpm exec stylelint --fix
- language: system
- files: '^packages/.*/src/.*/?.*.(css|scss|less)$'
- types: [file]
- - id: i18n
- name: i18n
- entry: make ci-i18n
- language: system
- files: '^packages/.*/src/.*/?.*.(js|jsx|ts|tsx)$'
- types: [file]
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
index 977db90..ebc82b2 100644
--- a/frontend/Dockerfile
+++ b/frontend/Dockerfile
@@ -21,7 +21,7 @@ EOT
FROM plone/frontend-prod-config:${VOLTO_VERSION}
LABEL maintainer="PloneGov-BR " \
- org.label-schema.name="pythonbrasil/pybr25-site-frontend" \
+ org.label-schema.name="pybr25-site-frontend" \
org.label-schema.description="PythonBrasil 2025 frontend image." \
org.label-schema.vendor="PloneGov-BR"
@@ -29,7 +29,7 @@ COPY --from=builder /app/ /app/
RUN < Cleaning Volto core and node_modules$(RESET)"
+ rm -rf core node_modules
.PHONY: install
install: ## Installs the add-on in a development environment
@@ -89,7 +93,7 @@ release-dry-run: ## Dry-run the release of the add-on on npmjs.org
test: ## Run unit tests
pnpm test
-.PHONY: test-ci
+.PHONY: ci-test
ci-test: ## Run unit tests in CI
# Unit Tests need the i18n to be built
VOLTOCONFIG=$(pwd)/volto.config.js pnpm --filter @plone/volto i18n
diff --git a/frontend/README.md b/frontend/README.md
index 2037143..ff45912 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -4,8 +4,8 @@ Encontro da comunidade Python Brasileira
[](https://www.npmjs.com/package/volto-pythonbrasil-site)
[](https://pythonbrasil.github.io/volto-pythonbrasil-site/)
-[](https://github.com/pythonbrasil/volto-pythonbrasil-site/actions/workflows/code.yml)
-[](https://github.com/pythonbrasil/volto-pythonbrasil-site/actions/workflows/unit.yml)
+[](https://github.com/pythonbrasil/pybr25-site/actions/workflows/main.yml)
+
## Features
@@ -16,9 +16,32 @@ Encontro da comunidade Python Brasileira
To install your project, you must choose the method appropriate to your version of Volto.
+### Volto 18 and later
+
+Add `volto-pythonbrasil-site` to your `package.json`.
+
+```json
+"dependencies": {
+ "volto-pythonbrasil-site": "*"
+}
+```
+
+Add `volto-pythonbrasil-site` to your `volto.config.js`.
+
+```javascript
+const addons = ['volto-pythonbrasil-site'];
+```
+
+If this package provides a Volto theme, and you want to activate it, then add the following to your `volto.config.js`.
+
+```javascript
+const theme = 'volto-pythonbrasil-site';
+```
+
### Volto 17 and earlier
-Create a new Volto project (you can skip this step if you already have one):
+Create a new Volto project.
+You can skip this step if you already have one.
```
npm install -g yo @plone/generator-volto
@@ -26,7 +49,7 @@ yo @plone/volto my-volto-project --addon volto-pythonbrasil-site
cd my-volto-project
```
-Add `volto-pythonbrasil-site` to your package.json:
+Add `volto-pythonbrasil-site` to your `package.json`.
```JSON
"addons": [
@@ -38,87 +61,60 @@ Add `volto-pythonbrasil-site` to your package.json:
}
```
-Download and install the new add-on by running:
+Download and install the new add-on.
```
yarn install
```
-Start volto with:
+Start Volto.
```
yarn start
```
-### Volto 18 and later
+## Test installation
-Add `volto-pythonbrasil-site` to your `package.json`:
+Visit http://localhost:3000/ in a browser, login, and check the awesome new features.
-```json
-"dependencies": {
- "volto-pythonbrasil-site": "*"
-}
-```
-Add `volto-pythonbrasil-site` to your `volto.config.js`:
+## Development
-```javascript
-const addons = ['volto-pythonbrasil-site'];
-```
+The development of this add-on is done in isolation using pnpm workspaces, the latest `mrs-developer`, and other Volto core improvements.
+For these reasons, it only works with pnpm and Volto 18.
-If this package provides a Volto theme, and you want to activate it, then add the following to your `volto.config.js`:
-```javascript
-const theme = 'volto-pythonbrasil-site';
-```
+### Prerequisites ✅
-## Test installation
+- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned.
+- [nvm](https://6.docs.plone.org/install/create-project-cookieplone.html#nvm)
+- [Node.js and pnpm](https://6.docs.plone.org/install/create-project.html#node-js) 22
+- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make)
+- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git)
+- [Docker](https://docs.docker.com/get-started/get-docker/) (optional)
-Visit http://localhost:3000/ in a browser, login, and check the awesome new features.
+### Installation 🔧
+1. Clone this repository, then change your working directory.
-## Development
+ ```shell
+ git clone git@github.com:pythonbrasil/pybr25-site.git
+ cd pybr25-site/frontend
+ ```
-The development of this add-on is done in isolation using a new approach using pnpm workspaces and latest `mrs-developer` and other Volto core improvements.
-For this reason, it only works with pnpm and Volto 18 (currently in alpha).
+2. Install this code base.
+ ```shell
+ make install
+ ```
-### Pre-requisites
-- [Node.js](https://6.docs.plone.org/install/create-project.html#node-js)
-- [Make](https://6.docs.plone.org/install/create-project.html#make)
-- [Docker](https://6.docs.plone.org/install/create-project.html#docker)
+### Make convenience commands
+Run `make help` to list the available Make commands.
-### Make convenience commands
-Run `make help` to list the available commands.
-
-```text
-help Show this help
-install Installs the add-on in a development environment
-start Starts Volto, allowing reloading of the add-on during development
-build Build a production bundle for distribution of the project with the add-on
-i18n Sync i18n
-ci-i18n Check if i18n is not synced
-format Format codebase
-lint Lint, or catch and remove problems, in code base
-release Release the add-on on npmjs.org
-release-dry-run Dry-run the release of the add-on on npmjs.org
-test Run unit tests
-ci-test Run unit tests in CI
-backend-docker-start Starts a Docker-based backend for development
-storybook-start Start Storybook server on port 6006
-storybook-build Build Storybook
-acceptance-frontend-dev-start Start acceptance frontend in development mode
-acceptance-frontend-prod-start Start acceptance frontend in production mode
-acceptance-backend-start Start backend acceptance server
-ci-acceptance-backend-start Start backend acceptance server in headless mode for CI
-acceptance-test Start Cypress in interactive mode
-ci-acceptance-test Run cypress tests in headless mode for CI
-```
-
-### Development environment set up
+### Set up development environment
Install package requirements.
@@ -197,7 +193,3 @@ make acceptance-test
## License
The project is licensed under the MIT license.
-
-## Credits and Acknowledgements 🙏
-
-Crafted with care by **Generated using [Cookieplone (0.8.2)](https://github.com/plone/cookieplone) and [cookiecutter-plone (2638336)](https://github.com/plone/cookiecutter-plone/commit/2638336ff1127c169063964cd95251292c954a0b) on 2025-01-31 11:19:23.755532**. A special thanks to all contributors and supporters!
diff --git a/frontend/cypress/tests/example.cy.js b/frontend/cypress/tests/example.cy.js
index f3a1fad..f102f27 100644
--- a/frontend/cypress/tests/example.cy.js
+++ b/frontend/cypress/tests/example.cy.js
@@ -9,11 +9,13 @@ context('Example Acceptance Tests', () => {
contentTitle: 'Test document',
});
cy.autologin();
+ cy.intercept('GET', '/**/document*').as('content');
});
it('As editor I can add edit a Page', function () {
cy.visit('/document');
cy.navigate('/document/edit');
+ cy.wait('@content');
cy.get('#toolbar-save').click();
});
});
diff --git a/frontend/mrs.developer.json b/frontend/mrs.developer.json
index 71a6b24..2b2bc7b 100644
--- a/frontend/mrs.developer.json
+++ b/frontend/mrs.developer.json
@@ -4,6 +4,6 @@
"package": "@plone/volto",
"url": "git@github.com:plone/volto.git",
"https": "https://github.com/plone/volto.git",
- "tag": "18.8.2"
+ "tag": "18.14.0"
}
}
diff --git a/frontend/package.json b/frontend/package.json
index e19d283..94e0bfc 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -3,7 +3,7 @@
"version": "1.0.0-alpha.0",
"description": "Encontro da comunidade Python Brasileira",
"author": "PloneGov-BR",
- "homepage": "https://github.com/pythonbrasil/volto-pythonbrasil-site",
+ "homepage": "https://github.com/pythonbrasil/pybr25-site",
"license": "MIT",
"keywords": [
"volto-addon",
@@ -35,7 +35,7 @@
"dependencies": {
"@plone/volto": "workspace:*",
"@plone/registry": "workspace:*",
- "volto-pythonbrasil-site": "workspace:*"
+ "@plonegovbr/volto-pythonbrasil-site": "workspace:*"
},
"devDependencies": {
"mrs-developer": "^2.2.0"
diff --git a/frontend/packages/volto-pythonbrasil-site/CHANGELOG.md b/frontend/packages/volto-pythonbrasil-site/CHANGELOG.md
index e24f3a8..da63824 100644
--- a/frontend/packages/volto-pythonbrasil-site/CHANGELOG.md
+++ b/frontend/packages/volto-pythonbrasil-site/CHANGELOG.md
@@ -3,7 +3,7 @@
diff --git a/frontend/packages/volto-pythonbrasil-site/locales/de/LC_MESSAGES/volto.po b/frontend/packages/volto-pythonbrasil-site/locales/de/LC_MESSAGES/volto.po
index 2d79602..51d36f7 100644
--- a/frontend/packages/volto-pythonbrasil-site/locales/de/LC_MESSAGES/volto.po
+++ b/frontend/packages/volto-pythonbrasil-site/locales/de/LC_MESSAGES/volto.po
@@ -5,82 +5,73 @@ msgstr ""
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
-"Language: \n"
+"Language: de\n"
"Language-Team: \n"
"Content-Type: \n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. Default: "Alignment"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Alignment"
msgstr ""
#. Default: "Call to Action"
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Call to Action"
msgstr ""
#. Default: "Chamada"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada"
msgstr ""
#. Default: "Chamada Principal"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada Principal"
msgstr ""
#. Default: "Chapéu"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Chapéu"
msgstr ""
#. Default: "Close menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Close menu"
msgstr ""
#. Default: "Imagem"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Imagem"
msgstr ""
#. Default: "Open menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Open menu"
msgstr ""
#. Default: "PythonBrasil 2025"
-#: components/Logo/Logo
+#: messages
msgid "PythonBrasil 2025"
msgstr ""
#. Default: "Sumário"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Sumário"
msgstr ""
#. Default: "Texto CTA"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Texto CTA"
msgstr ""
-#. Default: "Título"
-#: components/Blocks/GridCTA/schema
-msgid "Título"
-msgstr ""
-
#. Default: "URL"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "URL"
msgstr ""
#. Default: "Voltar para a capa"
-#: components/Logo/Logo
+#: messages
msgid "Voltar para a capa"
msgstr ""
diff --git a/frontend/packages/volto-pythonbrasil-site/locales/en/LC_MESSAGES/volto.po b/frontend/packages/volto-pythonbrasil-site/locales/en/LC_MESSAGES/volto.po
index d1342b4..42bd806 100644
--- a/frontend/packages/volto-pythonbrasil-site/locales/en/LC_MESSAGES/volto.po
+++ b/frontend/packages/volto-pythonbrasil-site/locales/en/LC_MESSAGES/volto.po
@@ -12,75 +12,66 @@ msgstr ""
"Plural-Forms: \n"
#. Default: "Alignment"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Alignment"
msgstr ""
#. Default: "Call to Action"
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Call to Action"
msgstr ""
#. Default: "Chamada"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada"
msgstr ""
#. Default: "Chamada Principal"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada Principal"
msgstr ""
#. Default: "Chapéu"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Chapéu"
msgstr ""
#. Default: "Close menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Close menu"
msgstr ""
#. Default: "Imagem"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Imagem"
msgstr ""
#. Default: "Open menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Open menu"
msgstr ""
#. Default: "PythonBrasil 2025"
-#: components/Logo/Logo
+#: messages
msgid "PythonBrasil 2025"
msgstr ""
#. Default: "Sumário"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Sumário"
msgstr ""
#. Default: "Texto CTA"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Texto CTA"
msgstr ""
-#. Default: "Título"
-#: components/Blocks/GridCTA/schema
-msgid "Título"
-msgstr ""
-
#. Default: "URL"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "URL"
msgstr ""
#. Default: "Voltar para a capa"
-#: components/Logo/Logo
+#: messages
msgid "Voltar para a capa"
msgstr ""
diff --git a/frontend/packages/volto-pythonbrasil-site/locales/es/LC_MESSAGES/volto.po b/frontend/packages/volto-pythonbrasil-site/locales/es/LC_MESSAGES/volto.po
index 9079d83..97eb80f 100644
--- a/frontend/packages/volto-pythonbrasil-site/locales/es/LC_MESSAGES/volto.po
+++ b/frontend/packages/volto-pythonbrasil-site/locales/es/LC_MESSAGES/volto.po
@@ -19,75 +19,66 @@ msgstr ""
"X-Generator: Poedit 2.2.1\n"
#. Default: "Alignment"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Alignment"
msgstr ""
#. Default: "Call to Action"
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Call to Action"
msgstr ""
#. Default: "Chamada"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada"
msgstr ""
#. Default: "Chamada Principal"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada Principal"
msgstr ""
#. Default: "Chapéu"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Chapéu"
msgstr ""
#. Default: "Close menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Close menu"
msgstr ""
#. Default: "Imagem"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Imagem"
msgstr ""
#. Default: "Open menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Open menu"
msgstr ""
#. Default: "PythonBrasil 2025"
-#: components/Logo/Logo
+#: messages
msgid "PythonBrasil 2025"
msgstr ""
#. Default: "Sumário"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Sumário"
msgstr ""
#. Default: "Texto CTA"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Texto CTA"
msgstr ""
-#. Default: "Título"
-#: components/Blocks/GridCTA/schema
-msgid "Título"
-msgstr ""
-
#. Default: "URL"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "URL"
msgstr ""
#. Default: "Voltar para a capa"
-#: components/Logo/Logo
+#: messages
msgid "Voltar para a capa"
msgstr ""
diff --git a/frontend/packages/volto-pythonbrasil-site/locales/pt_BR/LC_MESSAGES/volto.po b/frontend/packages/volto-pythonbrasil-site/locales/pt_BR/LC_MESSAGES/volto.po
index ff85423..aa3ed76 100644
--- a/frontend/packages/volto-pythonbrasil-site/locales/pt_BR/LC_MESSAGES/volto.po
+++ b/frontend/packages/volto-pythonbrasil-site/locales/pt_BR/LC_MESSAGES/volto.po
@@ -17,75 +17,66 @@ msgstr ""
"Domain: volto\n"
#. Default: "Alignment"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Alignment"
msgstr ""
#. Default: "Call to Action"
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Call to Action"
msgstr ""
#. Default: "Chamada"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada"
msgstr ""
#. Default: "Chamada Principal"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada Principal"
msgstr ""
#. Default: "Chapéu"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Chapéu"
msgstr ""
#. Default: "Close menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Close menu"
msgstr ""
#. Default: "Imagem"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Imagem"
msgstr ""
#. Default: "Open menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Open menu"
msgstr ""
#. Default: "PythonBrasil 2025"
-#: components/Logo/Logo
+#: messages
msgid "PythonBrasil 2025"
msgstr ""
#. Default: "Sumário"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Sumário"
msgstr ""
#. Default: "Texto CTA"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Texto CTA"
msgstr ""
-#. Default: "Título"
-#: components/Blocks/GridCTA/schema
-msgid "Título"
-msgstr ""
-
#. Default: "URL"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "URL"
msgstr ""
#. Default: "Voltar para a capa"
-#: components/Logo/Logo
+#: messages
msgid "Voltar para a capa"
msgstr ""
diff --git a/frontend/packages/volto-pythonbrasil-site/locales/volto.pot b/frontend/packages/volto-pythonbrasil-site/locales/volto.pot
index 8ad5c43..afdc318 100644
--- a/frontend/packages/volto-pythonbrasil-site/locales/volto.pot
+++ b/frontend/packages/volto-pythonbrasil-site/locales/volto.pot
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Plone\n"
-"POT-Creation-Date: 2025-01-31T20:16:07.561Z\n"
+"POT-Creation-Date: 2025-04-29T19:33:35.446Z\n"
"Last-Translator: Plone i18n \n"
"Language-Team: Plone i18n \n"
"Content-Type: text/plain; charset=utf-8\n"
@@ -14,75 +14,66 @@ msgstr ""
"Domain: volto\n"
#. Default: "Alignment"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Alignment"
msgstr ""
#. Default: "Call to Action"
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Call to Action"
msgstr ""
#. Default: "Chamada"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada"
msgstr ""
#. Default: "Chamada Principal"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Chamada Principal"
msgstr ""
#. Default: "Chapéu"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Chapéu"
msgstr ""
#. Default: "Close menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Close menu"
msgstr ""
#. Default: "Imagem"
-#: components/Blocks/Chamada/schema
+#: messages
msgid "Imagem"
msgstr ""
#. Default: "Open menu"
-#: components/Navigation/Navigation
+#: messages
msgid "Open menu"
msgstr ""
#. Default: "PythonBrasil 2025"
-#: components/Logo/Logo
+#: messages
msgid "PythonBrasil 2025"
msgstr ""
#. Default: "Sumário"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Sumário"
msgstr ""
#. Default: "Texto CTA"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "Texto CTA"
msgstr ""
-#. Default: "Título"
-#: components/Blocks/GridCTA/schema
-msgid "Título"
-msgstr ""
-
#. Default: "URL"
-#: components/Blocks/Chamada/schema
-#: components/Blocks/GridCTA/schema
+#: messages
msgid "URL"
msgstr ""
#. Default: "Voltar para a capa"
-#: components/Logo/Logo
+#: messages
msgid "Voltar para a capa"
msgstr ""
diff --git a/frontend/packages/volto-pythonbrasil-site/news/+social.feature b/frontend/packages/volto-pythonbrasil-site/news/+social.feature
new file mode 100644
index 0000000..74b41e2
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/news/+social.feature
@@ -0,0 +1 @@
+Add @plonegovbr/volto-social-media as a dependency. @ericof
diff --git a/frontend/packages/volto-pythonbrasil-site/news/+vlt.feature b/frontend/packages/volto-pythonbrasil-site/news/+vlt.feature
new file mode 100644
index 0000000..4eaf6d0
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/news/+vlt.feature
@@ -0,0 +1 @@
+Upgrade @kitconcept/volto-light-theme to version 6.0.0-alpha.22 @ericof
diff --git a/frontend/packages/volto-pythonbrasil-site/news/+volto.feature b/frontend/packages/volto-pythonbrasil-site/news/+volto.feature
new file mode 100644
index 0000000..1dda9dc
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/news/+volto.feature
@@ -0,0 +1 @@
+Upgrade @plone/volto to version 18.14.0 @ericof
diff --git a/frontend/packages/volto-pythonbrasil-site/package.json b/frontend/packages/volto-pythonbrasil-site/package.json
index 8b6b675..8034c12 100644
--- a/frontend/packages/volto-pythonbrasil-site/package.json
+++ b/frontend/packages/volto-pythonbrasil-site/package.json
@@ -1,6 +1,6 @@
{
- "name": "volto-pythonbrasil-site",
- "version": "1.0.0-alpha.0",
+ "name": "@plonegovbr/volto-pythonbrasil-site",
+ "version": "20250212.1.0",
"description": "Encontro da comunidade Python Brasileira",
"main": "src/index.js",
"license": "MIT",
@@ -11,10 +11,10 @@
"react"
],
"author": "PloneGov-BR",
- "homepage": "https://github.com/pythonbrasil/volto-pythonbrasil-site#readme",
+ "homepage": "https://github.com/pythonbrasil/pybr25-site#readme",
"repository": {
"type": "git",
- "url": "git@github.com:pythonbrasil/volto-pythonbrasil-site.git"
+ "url": "git@github.com:pythonbrasil/pybr25-site"
},
"publishConfig": {
"access": "public"
@@ -32,47 +32,36 @@
"@kitconcept/volto-social-blocks",
"@mbarde/volto-image-crop-widget",
"volto-form-block",
- "@plonegovbr/volto-network-block",
+ "@plonegovbr/volto-social-media",
"@kitconcept/volto-separator-block",
"@kitconcept/volto-button-block",
"@eeacms/volto-statistic-block",
"@plone-collective/volto-authomatic",
"@plone-collective/volto-eventbrite-block",
"@kitconcept/volto-heading-block",
- "@kitconcept/volto-testimonials-block",
- "@kitconcept/volto-quote-block",
"@kitconcept/volto-light-theme",
"@eeacms/volto-matomo"
],
"dependencies": {
"@plone/components": "workspace:*",
- "@eeacms/volto-accordion-block": "11.0.0",
- "@eeacms/volto-matomo": "^5.0.0",
- "@eeacms/volto-statistic-block": "5.0.1",
- "@kitconcept/volto-button-block": "3.0.3",
- "@kitconcept/volto-light-theme": "^5.0.2",
- "@kitconcept/volto-heading-block": "^2.4.0",
- "@kitconcept/volto-separator-block": "^4.1.2",
- "@kitconcept/volto-slider-block": "^6.3.1",
- "@kitconcept/volto-social-blocks": "1.0.0-alpha.4",
- "@kitconcept/volto-testimonials-block": "1.0.4",
- "@kitconcept/volto-quote-block": "1.1.2",
+ "@plone/registry": "workspace:*",
+ "@eeacms/volto-matomo": "*",
+ "@eeacms/volto-statistic-block": "*",
+ "@kitconcept/volto-light-theme": "^6.0.0-alpha.22",
+ "@kitconcept/volto-social-blocks": "1.0.0-alpha.8",
"@mbarde/volto-image-crop-widget": "0.5.1",
"@plone-collective/volto-authomatic": "2.0.1",
"@plone-collective/volto-eventbrite-block": "^1.0.0-alpha.2",
- "@plonegovbr/volto-network-block": "^1.0.0",
- "classnames": "2.2.6",
- "embla-carousel-autoplay": "^8.0.0",
- "embla-carousel-react": "^8.0.0",
- "react-lazy-load-image-component": "^1.6.2",
- "volto-form-block": "^3.10.2"
+ "@plonegovbr/volto-social-media": "^2.0.0-alpha.5",
+ "volto-form-block": "*"
},
"peerDependencies": {
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
- "@plone/scripts": "^3.6.1",
+ "@plone/scripts": "workspace:*",
+ "@plone/types": "workspace:*",
"release-it": "^17.1.1"
}
}
diff --git a/frontend/packages/volto-pythonbrasil-site/public/android-chrome-192x192.png b/frontend/packages/volto-pythonbrasil-site/public/android-chrome-192x192.png
index 85c557e..53e6915 100644
Binary files a/frontend/packages/volto-pythonbrasil-site/public/android-chrome-192x192.png and b/frontend/packages/volto-pythonbrasil-site/public/android-chrome-192x192.png differ
diff --git a/frontend/packages/volto-pythonbrasil-site/public/android-chrome-512x512.png b/frontend/packages/volto-pythonbrasil-site/public/android-chrome-512x512.png
index f979f0f..01a2b8e 100644
Binary files a/frontend/packages/volto-pythonbrasil-site/public/android-chrome-512x512.png and b/frontend/packages/volto-pythonbrasil-site/public/android-chrome-512x512.png differ
diff --git a/frontend/packages/volto-pythonbrasil-site/public/apple-touch-icon.png b/frontend/packages/volto-pythonbrasil-site/public/apple-touch-icon.png
index cba38aa..6f87d6a 100644
Binary files a/frontend/packages/volto-pythonbrasil-site/public/apple-touch-icon.png and b/frontend/packages/volto-pythonbrasil-site/public/apple-touch-icon.png differ
diff --git a/frontend/packages/volto-pythonbrasil-site/public/favicon-16x16.png b/frontend/packages/volto-pythonbrasil-site/public/favicon-16x16.png
index 72e1f31..e529d3b 100644
Binary files a/frontend/packages/volto-pythonbrasil-site/public/favicon-16x16.png and b/frontend/packages/volto-pythonbrasil-site/public/favicon-16x16.png differ
diff --git a/frontend/packages/volto-pythonbrasil-site/public/favicon-32x32.png b/frontend/packages/volto-pythonbrasil-site/public/favicon-32x32.png
index 38aa1d4..eabd1cd 100644
Binary files a/frontend/packages/volto-pythonbrasil-site/public/favicon-32x32.png and b/frontend/packages/volto-pythonbrasil-site/public/favicon-32x32.png differ
diff --git a/frontend/packages/volto-pythonbrasil-site/public/favicon.ico b/frontend/packages/volto-pythonbrasil-site/public/favicon.ico
index 791a433..4e14007 100644
Binary files a/frontend/packages/volto-pythonbrasil-site/public/favicon.ico and b/frontend/packages/volto-pythonbrasil-site/public/favicon.ico differ
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/DefaultView.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/DefaultView.jsx
index 65e0ee9..c0b530c 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/DefaultView.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/DefaultView.jsx
@@ -1,19 +1,18 @@
import React from 'react';
import { Button, Container, ArrowrightIcon } from '@plone/components';
-import { UniversalLink } from '@plone/volto/components';
-import { isInternalURL } from '@plone/volto/helpers';
-import { MaybeWrap } from '@plone/volto/components';
+import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
+import { isInternalURL } from '@plone/volto/helpers/Url/Url';
+import MaybeWrap from '@plone/volto/components/manage/MaybeWrap/MaybeWrap';
import config from '@plone/volto/registry';
-import PropTypes from 'prop-types';
const ChamadaView = (props) => {
const Image = config.getComponent('Image').component;
- const { className, data, isEditMode } = props;
+ const { className, data, isEditMode, style } = props;
const { title, head_title, description, preview_image, label, href } = data;
const url = href?.[0]?.['@id'] ? href[0]['@id'] : href;
const image = preview_image?.[0];
return (
-
+
{
);
};
-/**
- * Property types.
- * @property {Object} propTypes Property types.
- * @static
- */
-ChamadaView.propTypes = {
- title: PropTypes.string,
-};
-
-/**
- * Default properties.
- * @property {Object} defaultProps Default properties.
- * @static
- */
-ChamadaView.defaultProps = {
- title: 'Hello World!',
-};
-
export default ChamadaView;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/Edit.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/Edit.jsx
index e66ae8b..8b27209 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/Edit.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/Edit.jsx
@@ -1,6 +1,6 @@
import React from 'react';
-import { withBlockExtensions } from '@plone/volto/helpers';
-import { SidebarPortal } from '@plone/volto/components';
+import { withBlockExtensions } from '@plone/volto/helpers/Extensions';
+import SidebarPortal from '@plone/volto/components/manage/Sidebar/SidebarPortal';
import ChamadaBlockData from './Data';
import ChamadaBlockView from './View';
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/View.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/View.jsx
index ee30a81..3707c9c 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/View.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/View.jsx
@@ -1,11 +1,16 @@
import React from 'react';
-import { withBlockExtensions } from '@plone/volto/helpers';
+import { withBlockExtensions } from '@plone/volto/helpers/Extensions';
import ChamadaView from './DefaultView';
const ChamadaBlockView = (props) => {
- const { data, isEditMode, className } = props;
+ const { data, isEditMode, className, style } = props;
return (
-
+
);
};
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/schema.js b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/schema.js
index 635a10d..04cd9b3 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/schema.js
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/Chamada/schema.js
@@ -1,45 +1,10 @@
-import { defineMessages } from 'react-intl';
+import messages from '@plonegovbr/volto-pythonbrasil-site/messages';
import { addStyling } from '@plone/volto/helpers/Extensions/withBlockSchemaEnhancer';
-const messages = defineMessages({
- blockTitle: {
- id: 'Chamada Principal',
- defaultMessage: 'Chamada Principal',
- },
- head_title: {
- id: 'Chapéu',
- defaultMessage: 'Chapéu',
- },
- image: {
- id: 'Imagem',
- defaultMessage: 'Imagem',
- },
- align: {
- id: 'Alignment',
- defaultMessage: 'Alignment',
- },
- title: {
- id: 'Chamada',
- defaultMessage: 'Chamada',
- },
- description: {
- id: 'Sumário',
- defaultMessage: 'Sumário',
- },
- ctaLabel: {
- id: 'Texto CTA',
- defaultMessage: 'Texto CTA',
- },
- ctaHref: {
- id: 'URL',
- defaultMessage: 'URL',
- },
-});
-
export const chamadaSchema = (props) => {
const { intl } = props;
const schema = {
- title: props.intl.formatMessage(messages.blockTitle),
+ title: props.intl.formatMessage(messages.blockChamada),
fieldsets: [
{
id: 'default',
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/DefaultView.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/DefaultView.jsx
index 8cfc7ca..8106c64 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/DefaultView.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/DefaultView.jsx
@@ -1,16 +1,16 @@
import React from 'react';
import { Button, Container, ArrowrightIcon } from '@plone/components';
-import { UniversalLink } from '@plone/volto/components';
-import { isInternalURL } from '@plone/volto/helpers';
-import { MaybeWrap } from '@plone/volto/components';
+import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
+import { isInternalURL } from '@plone/volto/helpers/Url/Url';
+import MaybeWrap from '@plone/volto/components/manage/MaybeWrap/MaybeWrap';
import PropTypes from 'prop-types';
const GridCTAView = (props) => {
- const { className, data, isEditMode } = props;
+ const { className, data, isEditMode, style } = props;
const { title, head_title, description, label, href } = data;
const url = href?.[0]?.['@id'] ? href[0]['@id'] : href;
return (
-
+
{head_title}
{title}
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/Edit.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/Edit.jsx
index 62b48ba..84f7a08 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/Edit.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/Edit.jsx
@@ -1,16 +1,14 @@
import React from 'react';
-import { withBlockExtensions } from '@plone/volto/helpers';
-import { SidebarPortal } from '@plone/volto/components';
+import { withBlockExtensions } from '@plone/volto/helpers/Extensions';
+import SidebarPortal from '@plone/volto/components/manage/Sidebar/SidebarPortal';
import GridCTABlockData from './Data';
import GridCTABlockView from './View';
const GridCTABlockEdit = (props) => {
const { data, onChangeBlock, block, selected } = props;
- const backgroundColor = data.styles?.backgroundColor;
- const className = backgroundColor
- ? `has--backgroundColor--${backgroundColor}`
- : '';
+ const theme = data?.theme ? data.theme : data.styles?.theme;
+ const className = theme ? `has--theme--${theme}` : '';
return (
<>
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/View.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/View.jsx
index 10bc257..5412da6 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/View.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/View.jsx
@@ -1,11 +1,16 @@
import React from 'react';
-import { withBlockExtensions } from '@plone/volto/helpers';
+import { withBlockExtensions } from '@plone/volto/helpers/Extensions';
import GridCTAView from './DefaultView';
const GridCTABlockView = (props) => {
- const { data, isEditMode, className } = props;
+ const { data, isEditMode, className, style } = props;
return (
-
+
);
};
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/schema.js b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/schema.js
index 18c9fc5..56f6999 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/schema.js
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Blocks/GridCTA/schema.js
@@ -1,35 +1,8 @@
-import { defineMessages } from 'react-intl';
-
-const messages = defineMessages({
- blockTitle: {
- id: 'Call to Action',
- defaultMessage: 'Call to Action',
- },
- head_title: {
- id: 'Chapéu',
- defaultMessage: 'Chapéu',
- },
- title: {
- id: 'Título',
- defaultMessage: 'Título',
- },
- description: {
- id: 'Sumário',
- defaultMessage: 'Sumário',
- },
- ctaLabel: {
- id: 'Texto CTA',
- defaultMessage: 'Texto CTA',
- },
- ctaHref: {
- id: 'URL',
- defaultMessage: 'URL',
- },
-});
+import messages from '@plonegovbr/volto-pythonbrasil-site/messages';
export const gridCTASchema = (props) => {
const schema = {
- title: props.intl.formatMessage(messages.blockTitle),
+ title: props.intl.formatMessage(messages.blockGridCTA),
fieldsets: [
{
id: 'default',
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/Footer.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/Footer.jsx
deleted file mode 100644
index 5cc1b18..0000000
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/Footer.jsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import React from 'react';
-import { Container } from '@plone/components';
-import { UniversalLink } from '@plone/volto/components';
-import { flattenToAppURL } from '@plone/volto/helpers';
-import FooterLinks from '@plonegovbr/volto-network-block/components/FooterLinks/FooterLinks';
-
-const siteActions = [
- { id: 'contact', title: 'Fale Conosco', url: '/evento/contato' },
- {
- id: 'faq',
- title: 'Perguntas Frequentes',
- url: '/evento/perguntas-frequentes',
- },
- {
- id: 'code-of-conduct',
- title: 'Código de Conduta',
- url: '/evento/codigo-de-conduta',
- },
-];
-
-/**
- * Component to display the footer.
- * @function Footer
- * @param {Object} intl Intl object
- * @returns {string} Markup of the component
- */
-const Footer = ({ intl }) => {
- return (
-
- );
-};
-
-export default Footer;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Colophon.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Colophon.jsx
new file mode 100644
index 0000000..a4513a4
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Colophon.jsx
@@ -0,0 +1,24 @@
+import React from 'react';
+import { Container } from '@plone/components';
+import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
+
+const Colophon = () => {
+ return (
+
+ Site feito com{' '}
+
+ ❤️
+ {' '}
+ pela comunidade{' '}
+
+ PloneGov-BR
+
+
+ );
+};
+
+export default Colophon;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Empty.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Empty.jsx
new file mode 100644
index 0000000..28ef27b
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Empty.jsx
@@ -0,0 +1,5 @@
+const Empty = () => {
+ return ;
+};
+
+export default Empty;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/FollowUs.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/FollowUs.jsx
new file mode 100644
index 0000000..3a64cda
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/FollowUs.jsx
@@ -0,0 +1,12 @@
+import React from 'react';
+import FooterLinks from '@plonegovbr/volto-social-media/components/FooterLinks/FooterLinks';
+
+const FollowUs = () => {
+ return (
+ <>
+
+ >
+ );
+};
+
+export default FollowUs;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Links.tsx b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Links.tsx
new file mode 100644
index 0000000..22e5b4b
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/Links.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+import isEmpty from 'lodash/isEmpty';
+import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
+import { useLiveData } from '@kitconcept/volto-light-theme/helpers/useLiveData';
+import type { SiteFooterSettings } from '@kitconcept/volto-light-theme/types';
+import { Container } from '@plone/components';
+import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
+import type { Content } from '@plone/types';
+
+const Links = ({ content }: { content: Content }) => {
+ const links = useLiveData(
+ content,
+ 'pythonbrasil.footer',
+ 'footer_links',
+ );
+ return (
+
+
+ {links && Array.isArray(links)
+ ? links.map((link) => {
+ if (isEmpty(link) || !link.href) return null;
+
+ const title = link.title || link.href[0]['title'];
+ const href = flattenToAppURL(link.href[0]?.['@id']);
+
+ if (!href) return null;
+
+ return (
+ -
+
+ {title}
+
+
+ );
+ })
+ : null}
+
+
+ );
+};
+
+export default Links;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/MainFooter.tsx b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/MainFooter.tsx
new file mode 100644
index 0000000..3e3478d
--- /dev/null
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Footer/slots/MainFooter.tsx
@@ -0,0 +1,12 @@
+import { Container } from '@plone/components';
+import SlotRenderer from '@plone/volto/components/theme/SlotRenderer/SlotRenderer';
+
+const MainFooter = ({ content }) => {
+ return (
+
+
+
+ );
+};
+
+export default MainFooter;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Header/Header.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Header/Header.jsx
index 94da478..15010cf 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Header/Header.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Header/Header.jsx
@@ -1,8 +1,8 @@
import { Container } from '@plone/components';
import MobileNavigation from '@kitconcept/volto-light-theme/components/MobileNavigation/MobileNavigation';
import cx from 'classnames';
-
-import { Logo, Navigation } from '@plone/volto/components';
+import Logo from '@plonegovbr/volto-pythonbrasil-site/components/Logo/Logo';
+import Navigation from '@plonegovbr/volto-pythonbrasil-site/components/Navigation/Navigation';
const Header = (props) => {
const { pathname } = props;
diff --git a/frontend/packages/volto-pythonbrasil-site/src/components/Logo/Logo.jsx b/frontend/packages/volto-pythonbrasil-site/src/components/Logo/Logo.jsx
index d167832..c33b1ec 100644
--- a/frontend/packages/volto-pythonbrasil-site/src/components/Logo/Logo.jsx
+++ b/frontend/packages/volto-pythonbrasil-site/src/components/Logo/Logo.jsx
@@ -1,19 +1,9 @@
-import { defineMessages, useIntl } from 'react-intl';
-import { UniversalLink } from '@plone/volto/components';
+import { useIntl } from 'react-intl';
+import messages from '@plonegovbr/volto-pythonbrasil-site/messages';
+import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
import LogoFullImage from './logo.svg';
import LogoSlimImage from './logo-slim.svg';
-const messages = defineMessages({
- site: {
- id: 'PythonBrasil 2025',
- defaultMessage: 'PythonBrasil 2025',
- },
- homepage: {
- id: 'Voltar para a capa',
- defaultMessage: 'Voltar para a capa',
- },
-});
-
const LogoImg = ({ intl, logo }) => {
return (
{
const [desktopMenuOpen, setDesktopMenuOpen] = useState(null);
const [currentOpenIndex, setCurrentOpenIndex] = useState(null);
const navigation = useRef(null);
const dispatch = useDispatch();
const intl = useIntl();
- const enableFatMenu = config.settings.enableFatMenu;
const lang = useSelector((state) => state.intl.locale);
const token = useSelector((state) => state.userSession.token, shallowEqual);
@@ -105,7 +96,7 @@ const Navigation = ({ pathname }) => {
const itemId = itemURL ? itemURL[itemURL.length - 1] : '';
return (
- {enableFatMenu && hasItems ? (
+ {hasItems ? (
<>