diff --git a/.github/workflows/.hatch-run.yml b/.github/workflows/.hatch-run.yml deleted file mode 100644 index b312869e4..000000000 --- a/.github/workflows/.hatch-run.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: hatch-run - -on: - workflow_call: - inputs: - job-name: - required: true - type: string - hatch-run: - required: true - type: string - runs-on-array: - required: false - type: string - default: '["ubuntu-latest"]' - python-version-array: - required: false - type: string - default: '["3.x"]' - node-registry-url: - required: false - type: string - default: "" - secrets: - node-auth-token: - required: false - pypi-username: - required: false - pypi-password: - required: false - -jobs: - hatch: - name: ${{ format(inputs.job-name, matrix.python-version, matrix.runs-on) }} - strategy: - matrix: - python-version: ${{ fromJson(inputs.python-version-array) }} - runs-on: ${{ fromJson(inputs.runs-on-array) }} - runs-on: ${{ matrix.runs-on }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: "14.x" - registry-url: ${{ inputs.node-registry-url }} - - name: Pin NPM Version - run: npm install -g npm@8.19.3 - - name: Use Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install Python Dependencies - run: pip install hatch poetry - - name: Run Scripts - env: - NODE_AUTH_TOKEN: ${{ secrets.node-auth-token }} - PYPI_USERNAME: ${{ secrets.pypi-username }} - PYPI_PASSWORD: ${{ secrets.pypi-password }} - run: hatch run ${{ inputs.hatch-run }} diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index af768579c..000000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: check - -on: - push: - branches: - - main - pull_request: - branches: - - main - schedule: - - cron: "0 0 * * 0" - -jobs: - test-py-cov: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "python-{0}" - hatch-run: "test-py" - lint-py: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "python-{0}" - hatch-run: "lint-py" - test-py-matrix: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "python-{0} {1}" - hatch-run: "test-py --no-cov" - runs-on-array: '["ubuntu-latest", "macos-latest", "windows-latest"]' - python-version-array: '["3.9", "3.10", "3.11"]' - test-docs: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "python-{0}" - hatch-run: "test-docs" - test-js: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "{1}" - hatch-run: "test-js" - lint-js: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "{1}" - hatch-run: "lint-js" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index b4f77ee00..000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,71 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: codeql - -on: - push: - branches: [main] - pull_request: - # The branches below must be a subset of the branches above - branches: [main] - schedule: - - cron: "43 3 * * 3" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: ["javascript", "python"] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml deleted file mode 100644 index 7337f505b..000000000 --- a/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,30 +0,0 @@ -# This workflows will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -name: deploy-docs - -on: - push: - branches: - - "main" - tags: - - "*" - -jobs: - deploy-documentation: - runs-on: ubuntu-latest - steps: - - name: Check out src from Git - uses: actions/checkout@v2 - - name: Get history and tags for SCM versioning to work - run: | - git fetch --prune --unshallow - git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - name: Login to Heroku Container Registry - run: echo ${{ secrets.HEROKU_API_KEY }} | docker login -u ${{ secrets.HEROKU_EMAIL }} --password-stdin registry.heroku.com - - name: Build Docker Image - run: docker build . --file docs/Dockerfile --tag registry.heroku.com/${{ secrets.HEROKU_APP_NAME }}/web - - name: Push Docker Image - run: docker push registry.heroku.com/${{ secrets.HEROKU_APP_NAME }}/web - - name: Deploy - run: HEROKU_API_KEY=${{ secrets.HEROKU_API_KEY }} heroku container:release web --app ${{ secrets.HEROKU_APP_NAME }} diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 000000000..69342c994 --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,17 @@ +name: Publish Docs +on: + push: + branches: + - new-docs +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - run: pip install -r docs/requirements.txt + - run: mkdocs gh-deploy --force diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index e9271cbd5..000000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,20 +0,0 @@ -# This workflows will upload a Javscript Package using NPM to npmjs.org when a release is created -# For more information see: https://docs.github.com/en/actions/guides/publishing-nodejs-packages - -name: publish - -on: - release: - types: [published] - -jobs: - publish: - uses: ./.github/workflows/.hatch-run.yml - with: - job-name: "publish" - hatch-run: "publish" - node-registry-url: "https://registry.npmjs.org" - secrets: - node-auth-token: ${{ secrets.NODE_AUTH_TOKEN }} - pypi-username: ${{ secrets.PYPI_USERNAME }} - pypi-password: ${{ secrets.PYPI_PASSWORD }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..5ae0eb0af --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,199 @@ +# Changelog + +All notable changes to this project will be documented in this file. + + + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + + + + + +## [Unreleased] + +- Nothing (yet) + +## [2.2.0] - 2022-12-28 + +### Added + +- Add `options: QueryOptions` parameter to `use_query` to allow for configuration of this hook. + +### Changed + +- By default, `use_query` will recursively prefetch all many-to-many or many-to-one relationships to prevent `SynchronousOnlyOperation` exceptions. + +### Removed + +- `django_idom.hooks._fetch_lazy_fields` has been deleted. The equivalent replacement is `django_idom.utils.django_query_postprocessor`. + +## [2.1.0] - 2022-11-01 + +### Changed + +- Minimum `channels` version is now `4.0.0`. + +### Fixed + +- Change type hint on `view_to_component` callable to have `request` argument be optional. +- Change type hint on `view_to_component` to represent it as a decorator with parenthesis (such as `@view_to_component(compatibility=True)`) + +### Security + +- Add note to docs about potential information exposure via `view_to_component` when using `compatibility=True`. + +## [2.0.1] - 2022-10-18 + +### Fixed + +- Ability to use `key=...` parameter on all prefabricated components. + +## [2.0.0] - 2022-10-17 + +### Added + +- `use_origin` hook for returning the browser's `location.origin`. + +### Changed + +- `view_to_component` now returns a `Callable`, instead of directly returning a `Component`. Check the docs for new usage info. +- `use_mutation` and `use_query` will now log any query failures. + +### Fixed + +- Allow `use_mutation` to have `refetch=None`, as the docs suggest is possible. +- `use_query` will now prefetch all fields to prevent `SynchronousOnlyOperation` exceptions. +- `view_to_component`, `django_css`, and `django_js` type hints will now display like normal functions. +- IDOM preloader no longer attempts to parse commented out IDOM components. +- Tests are now fully functional on Windows + +## [1.2.0] - 2022-09-19 + +### Added + +- `auth_required` decorator to prevent your components from rendering to unauthenticated users. +- `use_query` hook for fetching database values. +- `use_mutation` hook for modifying database values. +- `view_to_component` utility to convert legacy Django views to IDOM components. + +### Changed + +- Bumped the minimum IDOM version to 0.40.2 +- Testing suite now uses `playwright` instead of `selenium` + +### Fixed + +- IDOM preloader is no longer sensitive to whitespace within template tags. + +## [1.1.0] - 2022-07-01 + +### Added + +- `django_css` and `django_js` components to defer loading CSS & JS files until needed. + +### Changed + +- Bumped the minimum IDOM version to 0.39.0 + +## [1.0.0] - 2022-05-22 + +### Added + +- Django-specific hooks! `use_websocket`, `use_scope`, and `use_location` are now available within the `django_idom.hooks` module. +- Documentation has been placed into a formal docs webpage. +- Logging for when a component fails to import, or if no components were found within Django. + +### Changed + +- `idom_component` template tag has been renamed to `component` +- Bumped the minimum IDOM version to 0.38.0 + +### Removed + +- `websocket` parameter for components has been removed. Functionally, it is replaced with `django_idom.hooks.use_websocket`. + +## [0.0.5] - 2022-04-04 + +### Changed + +- Bumped the minimum IDOM version to 0.37.2 + +### Fixed + +- ModuleNotFoundError: No module named `idom.core.proto` caused by IDOM 0.37.2 + +## [0.0.4] - 2022-03-05 + +### Changed + +- Bumped the minimum IDOM version to 0.37.1 + +## [0.0.3] - 2022-02-19 + +### Changed + +- Bumped the minimum IDOM version to 0.36.3 + +## [0.0.2] - 2022-01-30 + +### Added + +- Ability to declare the HTML class of the top-level component `div` +- `name = ...` parameter to IDOM HTTP paths for use with `django.urls.reverse()` +- Cache versioning to automatically invalidate old web module files from the cache back-end +- Automatic pre-population of the IDOM component registry +- Type hinting for `IdomWebsocket` + +### Changed + +- Fetching web modules from disk and/or cache is now fully async +- Static files are now contained within a `django_idom/` parent folder +- Upgraded IDOM to version `0.36.0` +- Minimum Django version required is now `4.0` +- Minimum Python version required is now `3.8` + +### Removed + +- `IDOM_WEB_MODULES_PATH` has been replaced with Django `include(...)` +- `IDOM_WS_MAX_RECONNECT_DELAY` has been renamed to `IDOM_WS_MAX_RECONNECT_TIMEOUT` +- `idom_web_modules` cache back-end has been renamed to `idom` + +### Fixed + +- Increase test timeout values to prevent false positives +- Windows compatibility for building Django-IDOM + +### Security + +- Fixed potential directory traversal attack on the IDOM web modules URL + +## [0.0.1] - 2021-08-18 + +### Added + +- Support for IDOM within the Django + +[unreleased]: https://github.com/idom-team/django-idom/compare/2.2.0...HEAD +[2.2.0]: https://github.com/idom-team/django-idom/compare/2.1.0...2.2.0 +[2.1.0]: https://github.com/idom-team/django-idom/compare/2.0.1...2.1.0 +[2.0.1]: https://github.com/idom-team/django-idom/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/idom-team/django-idom/compare/1.2.0...2.0.0 +[1.2.0]: https://github.com/idom-team/django-idom/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/idom-team/django-idom/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/idom-team/django-idom/compare/0.0.5...1.0.0 +[0.0.5]: https://github.com/idom-team/django-idom/compare/0.0.4...0.0.5 +[0.0.4]: https://github.com/idom-team/django-idom/compare/0.0.3...0.0.4 +[0.0.3]: https://github.com/idom-team/django-idom/compare/0.0.2...0.0.3 +[0.0.2]: https://github.com/idom-team/django-idom/compare/0.0.1...0.0.2 +[0.0.1]: https://github.com/idom-team/django-idom/releases/tag/0.0.1 diff --git a/README.md b/README.md index 83241e19a..d24c250a4 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,21 @@ -# ReactPy +Temporary branch being used to rewrite ReactPy's documentation. -

- - - - - - - - - - - - - - - -

+Many of these pages are in progress, and are using the [original ReactJS docs](https://react.dev/learn) as placeholders. +See live preview here: https://reactive-python.github.io/reactpy -[ReactPy](https://reactpy.dev/) is a library for building user interfaces in Python without Javascript. ReactPy interfaces are made from components that look and behave similar to those found in [ReactJS](https://reactjs.org/). Designed with simplicity in mind, ReactPy can be used by those without web development experience while also being powerful enough to grow with your ambitions. +In order to set up an environment to develop these docs... - - - - - - - - - - - - - - - -
Supported Backends
Built-inExternal
- - Flask, FastAPI, Sanic, Tornado - - - Django, - Jupyter, - Plotly-Dash -
+1. Install [Python](https://www.python.org/downloads/) 3.9 or higher +2. Fork and clone this repository +3. _Optional_: Create a Python virtual environment with the following command: `python3 -m venv venv` +4. _Optional_: Activate the virtual environment (this method will vary based on operating system) +5. Install the dependencies with the following command: `pip install -r docs/requirements.txt` +6. Run the following command: `mkdocs serve` +7. Follow the on-screen prompts to view the documentation in your browser +8. You can now edit the markdown files located within `docs/src/` and see the changes in real time -# At a Glance +🚧 : Unfinished tab +đŸšĢ : Tab is blocked from being started due to external factors -To get a rough idea of how to write apps in ReactPy, take a look at this tiny _Hello World_ application. - -```python -from reactpy import component, html, run - -@component -def hello_world(): - return html.h1("Hello, World!") - -run(hello_world) -``` - -# Resources - -Follow the links below to find out more about this project. - -- [Try ReactPy (Jupyter Notebook)](https://mybinder.org/v2/gh/reactive-python/reactpy-jupyter/main?urlpath=lab/tree/notebooks/introduction.ipynb) -- [Documentation](https://reactpy.dev/) -- [GitHub Discussions](https://github.com/reactive-python/reactpy/discussions) -- [Discord](https://discord.gg/uNb5P4hA9X) -- [Contributor Guide](https://reactpy.dev/docs/about/contributor-guide.html) -- [Code of Conduct](https://github.com/reactive-python/reactpy/blob/main/CODE_OF_CONDUCT.md) +Feel free to PR this branch with any changes you make to the documentation. If you have any questions, feel free to ask in the [Discord server](https://discord.gg/uNb5P4hA9X). diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index ea38eebf8..000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build -source/_auto -source/_static/custom.js -source/vdom-json-schema.json diff --git a/docs/Dockerfile b/docs/Dockerfile deleted file mode 100644 index 76a8ad7ee..000000000 --- a/docs/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -FROM python:3.9 - -WORKDIR /app/ - -# Install NodeJS -# -------------- -RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - -RUN apt-get install -yq nodejs build-essential -RUN npm install -g npm@8.5.0 - -# Install Poetry -# -------------- -RUN pip install poetry - -# Create/Activate Python Venv -# --------------------------- -ENV VIRTUAL_ENV=/opt/venv -RUN python3 -m venv $VIRTUAL_ENV -ENV PATH="$VIRTUAL_ENV/bin:$PATH" -RUN pip install --upgrade pip - -# Copy Files -# ---------- -COPY LICENSE ./ -COPY src ./src -COPY docs ./docs -COPY branding ./branding - -# Install and Build Docs -# ---------------------- -WORKDIR /app/docs -RUN poetry install -RUN sphinx-build -v -W -b html source build - -# Define Entrypoint -# ----------------- -ENV PORT 5000 -ENV REACTPY_DEBUG_MODE=1 -ENV REACTPY_CHECK_VDOM_SPEC=0 -CMD python main.py diff --git a/docs/LICENSE.md b/docs/LICENSE.md new file mode 100644 index 000000000..d21a91a91 --- /dev/null +++ b/docs/LICENSE.md @@ -0,0 +1,393 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 1360bc825..000000000 --- a/docs/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# ReactPy's Documentation - -We provide two main ways to run the docs. Both use -[`nox`](https://pypi.org/project/nox/): - -- `nox -s docs` - displays the docs and rebuilds when files are modified. -- `nox -s docs-in-docker` - builds a docker image and runs the docs from there. - -If any changes to the core of the documentation are made (i.e. to non-`*.rst` files), -then you should run a manual test of the documentation using the `docs_in_docker` -session. - -If you wish to build and run the docs by hand you need to perform two commands, each -being run from the root of the repository: - -- `sphinx-build -b html docs/source docs/build` -- `python scripts/run_docs.py` - -The first command constructs the static HTML and any Javascript. The latter actually -runs the web server that serves the content. diff --git a/docs/docs_app/app.py b/docs/docs_app/app.py deleted file mode 100644 index 3fe4669ff..000000000 --- a/docs/docs_app/app.py +++ /dev/null @@ -1,59 +0,0 @@ -from logging import getLogger -from pathlib import Path - -from sanic import Sanic, response - -from docs_app.examples import get_normalized_example_name, load_examples -from reactpy import component -from reactpy.backend.sanic import Options, configure, use_request -from reactpy.core.types import ComponentConstructor - -THIS_DIR = Path(__file__).parent -DOCS_DIR = THIS_DIR.parent -DOCS_BUILD_DIR = DOCS_DIR / "build" - -REACTPY_MODEL_SERVER_URL_PREFIX = "/_reactpy" - -logger = getLogger(__name__) - - -REACTPY_MODEL_SERVER_URL_PREFIX = "/_reactpy" - - -@component -def Example(): - raw_view_id = use_request().get_args().get("view_id") - view_id = get_normalized_example_name(raw_view_id) - return _get_examples()[view_id]() - - -def _get_examples(): - if not _EXAMPLES: - _EXAMPLES.update(load_examples()) - return _EXAMPLES - - -def reload_examples(): - _EXAMPLES.clear() - _EXAMPLES.update(load_examples()) - - -_EXAMPLES: dict[str, ComponentConstructor] = {} - - -def make_app(name: str): - app = Sanic(name) - - app.static("/docs", str(DOCS_BUILD_DIR)) - - @app.route("/") - async def forward_to_index(_): - return response.redirect("/docs/index.html") - - configure( - app, - Example, - Options(url_prefix=REACTPY_MODEL_SERVER_URL_PREFIX), - ) - - return app diff --git a/docs/docs_app/dev.py b/docs/docs_app/dev.py deleted file mode 100644 index 5d661924d..000000000 --- a/docs/docs_app/dev.py +++ /dev/null @@ -1,104 +0,0 @@ -import asyncio -import os -import threading -import time -import webbrowser - -from sphinx_autobuild.cli import ( - Server, - _get_build_args, - _get_ignore_handler, - find_free_port, - get_builder, - get_parser, -) - -from docs_app.app import make_app, reload_examples -from reactpy.backend.sanic import serve_development_app -from reactpy.testing import clear_reactpy_web_modules_dir - -# these environment variable are used in custom Sphinx extensions -os.environ["REACTPY_DOC_EXAMPLE_SERVER_HOST"] = "127.0.0.1:5555" -os.environ["REACTPY_DOC_STATIC_SERVER_HOST"] = "" - - -def wrap_builder(old_builder): - # This is the bit that we're injecting to get the example components to reload too - - app = make_app("docs_dev_app") - - thread_started = threading.Event() - - def run_in_thread(): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - - server_started = asyncio.Event() - - async def set_thread_event_when_started(): - await server_started.wait() - thread_started.set() - - loop.run_until_complete( - asyncio.gather( - serve_development_app(app, "127.0.0.1", 5555, server_started), - set_thread_event_when_started(), - ) - ) - - threading.Thread(target=run_in_thread, daemon=True).start() - - thread_started.wait() - - def new_builder(): - clear_reactpy_web_modules_dir() - reload_examples() - old_builder() - - return new_builder - - -def main(): - # Mostly copied from https://github.com/executablebooks/sphinx-autobuild/blob/b54fb08afc5112bfcda1d844a700c5a20cd6ba5e/src/sphinx_autobuild/cli.py - parser = get_parser() - args = parser.parse_args() - - srcdir = os.path.realpath(args.sourcedir) - outdir = os.path.realpath(args.outdir) - if not os.path.exists(outdir): - os.makedirs(outdir) - - server = Server() - - build_args, pre_build_commands = _get_build_args(args) - builder = wrap_builder( - get_builder( - server.watcher, - build_args, - host=args.host, - port=args.port, - pre_build_commands=pre_build_commands, - ) - ) - - ignore_handler = _get_ignore_handler(args) - server.watch(srcdir, builder, ignore=ignore_handler) - for dirpath in args.additional_watched_dirs: - real_dirpath = os.path.realpath(dirpath) - server.watch(real_dirpath, builder, ignore=ignore_handler) - server.watch(outdir, ignore=ignore_handler) - - if not args.no_initial_build: - builder() - - # Find the free port - portn = args.port or find_free_port() - if args.openbrowser is True: - - def opener(): - time.sleep(args.delay) - webbrowser.open(f"http://{args.host}:{args.port}/index.html") - - threading.Thread(target=opener, daemon=True).start() - - server.serve(port=portn, host=args.host, root=outdir) diff --git a/docs/docs_app/examples.py b/docs/docs_app/examples.py deleted file mode 100644 index a71a0b111..000000000 --- a/docs/docs_app/examples.py +++ /dev/null @@ -1,177 +0,0 @@ -from __future__ import annotations - -from collections.abc import Iterator -from io import StringIO -from pathlib import Path -from traceback import format_exc -from typing import Callable - -import reactpy -from reactpy.types import ComponentType - -HERE = Path(__file__) -SOURCE_DIR = HERE.parent.parent / "source" -CONF_FILE = SOURCE_DIR / "conf.py" -RUN_ReactPy = reactpy.run - - -def load_examples() -> Iterator[tuple[str, Callable[[], ComponentType]]]: - for name in all_example_names(): - yield name, load_one_example(name) - - -def all_example_names() -> set[str]: - names = set() - for file in _iter_example_files(SOURCE_DIR): - path = file.parent if file.name == "main.py" else file - names.add("/".join(path.relative_to(SOURCE_DIR).with_suffix("").parts)) - return names - - -def load_one_example(file_or_name: Path | str) -> Callable[[], ComponentType]: - return lambda: ( - # we use a lambda to ensure each instance is fresh - _load_one_example(file_or_name) - ) - - -def get_normalized_example_name( - name: str, relative_to: str | Path | None = SOURCE_DIR -) -> str: - return "/".join( - _get_root_example_path_by_name(name, relative_to).relative_to(SOURCE_DIR).parts - ) - - -def get_main_example_file_by_name( - name: str, relative_to: str | Path | None = SOURCE_DIR -) -> Path: - path = _get_root_example_path_by_name(name, relative_to) - if path.is_dir(): - return path / "main.py" - else: - return path.with_suffix(".py") - - -def get_example_files_by_name( - name: str, relative_to: str | Path | None = SOURCE_DIR -) -> list[Path]: - path = _get_root_example_path_by_name(name, relative_to) - if path.is_dir(): - return [p for p in path.glob("*") if not p.is_dir()] - else: - path = path.with_suffix(".py") - return [path] if path.exists() else [] - - -def _iter_example_files(root: Path) -> Iterator[Path]: - for path in root.iterdir(): - if path.is_dir(): - if not path.name.startswith("_") or path.name == "_examples": - yield from _iter_example_files(path) - elif path.suffix == ".py" and path != CONF_FILE: - yield path - - -def _load_one_example(file_or_name: Path | str) -> ComponentType: - if isinstance(file_or_name, str): - file = get_main_example_file_by_name(file_or_name) - else: - file = file_or_name - - if not file.exists(): - raise FileNotFoundError(str(file)) - - print_buffer = _PrintBuffer() - - def capture_print(*args, **kwargs): - buffer = StringIO() - print(*args, file=buffer, **kwargs) - print_buffer.write(buffer.getvalue()) - - captured_component_constructor = None - - def capture_component(component_constructor): - nonlocal captured_component_constructor - captured_component_constructor = component_constructor - - reactpy.run = capture_component - try: - code = compile(file.read_text(), str(file), "exec") - exec( - code, - { - "print": capture_print, - "__file__": str(file), - "__name__": file.stem, - }, - ) - except Exception: - return _make_error_display(format_exc()) - finally: - reactpy.run = RUN_ReactPy - - if captured_component_constructor is None: - return _make_example_did_not_run(str(file)) - - @reactpy.component - def Wrapper(): - return reactpy.html.div(captured_component_constructor(), PrintView()) - - @reactpy.component - def PrintView(): - text, set_text = reactpy.hooks.use_state(print_buffer.getvalue()) - print_buffer.set_callback(set_text) - return ( - reactpy.html.pre({"class_name": "printout"}, text) - if text - else reactpy.html.div() - ) - - return Wrapper() - - -def _get_root_example_path_by_name(name: str, relative_to: str | Path | None) -> Path: - if not name.startswith("/") and relative_to is not None: - rel_path = Path(relative_to) - rel_path = rel_path.parent if rel_path.is_file() else rel_path - else: - rel_path = SOURCE_DIR - return rel_path.joinpath(*name.split("/")).resolve() - - -class _PrintBuffer: - def __init__(self, max_lines: int = 10): - self._callback = None - self._lines = () - self._max_lines = max_lines - - def set_callback(self, function: Callable[[str], None]) -> None: - self._callback = function - - def getvalue(self) -> str: - return "".join(self._lines) - - def write(self, text: str) -> None: - if len(self._lines) == self._max_lines: - self._lines = self._lines[1:] + (text,) - else: - self._lines += (text,) - if self._callback is not None: - self._callback(self.getvalue()) - - -def _make_example_did_not_run(example_name): - @reactpy.component - def ExampleDidNotRun(): - return reactpy.html.code(f"Example {example_name} did not run") - - return ExampleDidNotRun() - - -def _make_error_display(message): - @reactpy.component - def ShowError(): - return reactpy.html.pre(message) - - return ShowError() diff --git a/docs/docs_app/prod.py b/docs/docs_app/prod.py deleted file mode 100644 index 0acf12432..000000000 --- a/docs/docs_app/prod.py +++ /dev/null @@ -1,14 +0,0 @@ -import os - -from docs_app.app import make_app - -app = make_app("docs_prod_app") - - -def main() -> None: - app.run( - host="0.0.0.0", # noqa: S104 - port=int(os.environ.get("PORT", 5000)), - workers=int(os.environ.get("WEB_CONCURRENCY", 1)), - debug=bool(int(os.environ.get("DEBUG", "0"))), - ) diff --git a/docs/examples/css/quick_start/adding_styles.css b/docs/examples/css/quick_start/adding_styles.css new file mode 100644 index 000000000..4d02060e1 --- /dev/null +++ b/docs/examples/css/quick_start/adding_styles.css @@ -0,0 +1,4 @@ +/* In your CSS */ +.avatar { + border-radius: 50%; +} diff --git a/docs/examples/css/quick_start/displaying_data.css b/docs/examples/css/quick_start/displaying_data.css new file mode 100644 index 000000000..9f5a392c1 --- /dev/null +++ b/docs/examples/css/quick_start/displaying_data.css @@ -0,0 +1,7 @@ +.avatar { + border-radius: 50%; +} + +.large { + border: 4px solid gold; +} diff --git a/docs/examples/css/quick_start/sharing_data_between_components.css b/docs/examples/css/quick_start/sharing_data_between_components.css new file mode 100644 index 000000000..6081b7ef4 --- /dev/null +++ b/docs/examples/css/quick_start/sharing_data_between_components.css @@ -0,0 +1,4 @@ +button { + display: block; + margin-bottom: 5px; +} diff --git a/docs/examples/css/quick_start/updating_the_screen.css b/docs/examples/css/quick_start/updating_the_screen.css new file mode 100644 index 000000000..6081b7ef4 --- /dev/null +++ b/docs/examples/css/quick_start/updating_the_screen.css @@ -0,0 +1,4 @@ +button { + display: block; + margin-bottom: 5px; +} diff --git a/docs/examples/css/responding_to_events/simple_button_event.css b/docs/examples/css/responding_to_events/simple_button_event.css new file mode 100644 index 000000000..4fc2d52a0 --- /dev/null +++ b/docs/examples/css/responding_to_events/simple_button_event.css @@ -0,0 +1,3 @@ +button { + margin-right: 10px; +} diff --git a/docs/examples/css/thinking_in_react/add_inverse_data_flow.css b/docs/examples/css/thinking_in_react/add_inverse_data_flow.css new file mode 100644 index 000000000..4be625123 --- /dev/null +++ b/docs/examples/css/thinking_in_react/add_inverse_data_flow.css @@ -0,0 +1,14 @@ +body { + padding: 5px; +} +label { + display: block; + margin-top: 5px; + margin-bottom: 5px; +} +th { + padding: 4px; +} +td { + padding: 2px; +} diff --git a/docs/examples/css/thinking_in_react/build_a_static_version_in_react.css b/docs/examples/css/thinking_in_react/build_a_static_version_in_react.css new file mode 100644 index 000000000..5b8624389 --- /dev/null +++ b/docs/examples/css/thinking_in_react/build_a_static_version_in_react.css @@ -0,0 +1,15 @@ +body { + padding: 5px; +} +label { + display: block; + margin-top: 5px; + margin-bottom: 5px; +} +th { + padding-top: 10px; +} +td { + padding: 2px; + padding-right: 40px; +} diff --git a/docs/examples/css/thinking_in_react/identify_where_your_state_should_live.css b/docs/examples/css/thinking_in_react/identify_where_your_state_should_live.css new file mode 100644 index 000000000..b811252a1 --- /dev/null +++ b/docs/examples/css/thinking_in_react/identify_where_your_state_should_live.css @@ -0,0 +1,14 @@ +body { + padding: 5px; +} +label { + display: block; + margin-top: 5px; + margin-bottom: 5px; +} +th { + padding-top: 5px; +} +td { + padding: 2px; +} diff --git a/docs/examples/css/tutorial_tic_tac_toe/setup_for_the_tutorial.css b/docs/examples/css/tutorial_tic_tac_toe/setup_for_the_tutorial.css new file mode 100644 index 000000000..e3efaf92a --- /dev/null +++ b/docs/examples/css/tutorial_tic_tac_toe/setup_for_the_tutorial.css @@ -0,0 +1,42 @@ +* { + box-sizing: border-box; +} + +body { + font-family: sans-serif; + margin: 20px; + padding: 0; +} + +.square { + background: #fff; + border: 1px solid #999; + float: left; + font-size: 24px; + font-weight: bold; + line-height: 34px; + height: 34px; + margin-right: -1px; + margin-top: -1px; + padding: 0; + text-align: center; + width: 34px; +} + +.board-row:after { + clear: both; + content: ""; + display: table; +} + +.status { + margin-bottom: 10px; +} +.game { + display: flex; + flex-direction: row; +} + +.game-info { + margin-left: 20px; +} diff --git a/docs/examples/css/tutorial_tic_tac_toe/tic_tac_toe.css b/docs/examples/css/tutorial_tic_tac_toe/tic_tac_toe.css new file mode 100644 index 000000000..87876ec02 --- /dev/null +++ b/docs/examples/css/tutorial_tic_tac_toe/tic_tac_toe.css @@ -0,0 +1,42 @@ +* { + box-sizing: border-box; +} + +body { + font-family: sans-serif; + margin: 20px; + padding: 0; +} + +.square { + background: #fff; + border: 1px solid #999; + float: left; + font-size: 24px; + font-weight: bold; + line-height: 34px; + height: 34px; + margin-right: -1px; + margin-top: -1px; + padding: 0; + text-align: center; + width: 34px; +} + +.board-row:after { + clear: both; + content: ""; + display: table; +} + +.status { + margin-bottom: 10px; +} +.game { + display: flex; + flex-direction: row; +} + +.game-info { + margin-left: 20px; +} diff --git a/docs/examples/json/thinking_in_react/start_with_the_mockup.json b/docs/examples/json/thinking_in_react/start_with_the_mockup.json new file mode 100644 index 000000000..f49a528b0 --- /dev/null +++ b/docs/examples/json/thinking_in_react/start_with_the_mockup.json @@ -0,0 +1,38 @@ +[ + { + "category": "Fruits", + "price": "$1", + "stocked": true, + "name": "Apple" + }, + { + "category": "Fruits", + "price": "$1", + "stocked": true, + "name": "Dragonfruit" + }, + { + "category": "Fruits", + "price": "$2", + "stocked": false, + "name": "Passionfruit" + }, + { + "category": "Vegetables", + "price": "$2", + "stocked": true, + "name": "Spinach" + }, + { + "category": "Vegetables", + "price": "$4", + "stocked": false, + "name": "Pumpkin" + }, + { + "category": "Vegetables", + "price": "$1", + "stocked": true, + "name": "Peas" + } +] diff --git a/docs/examples/python/quick_start/adding_styles.py b/docs/examples/python/quick_start/adding_styles.py new file mode 100644 index 000000000..cdc9a7b99 --- /dev/null +++ b/docs/examples/python/quick_start/adding_styles.py @@ -0,0 +1,4 @@ +from reactpy import html + +# start +html.img({"class_name": "avatar"}) diff --git a/docs/examples/python/quick_start/conditional_rendering.py b/docs/examples/python/quick_start/conditional_rendering.py new file mode 100644 index 000000000..d89e097a4 --- /dev/null +++ b/docs/examples/python/quick_start/conditional_rendering.py @@ -0,0 +1,22 @@ +from reactpy import component, html + + +def admin_panel(): + return [] + + +def login_form(): + return [] + + +is_logged_in = True + + +# start +@component +def my_component(): + if is_logged_in: + content = admin_panel() + else: + content = login_form() + return html.div(content) diff --git a/docs/examples/python/quick_start/conditional_rendering_logical_and.py b/docs/examples/python/quick_start/conditional_rendering_logical_and.py new file mode 100644 index 000000000..07e752bba --- /dev/null +++ b/docs/examples/python/quick_start/conditional_rendering_logical_and.py @@ -0,0 +1,14 @@ +from reactpy import component, html + + +def admin_panel(): + return [] + + +is_logged_in = True + + +# start +@component +def my_component(): + return html.div(is_logged_in and admin_panel()) diff --git a/docs/examples/python/quick_start/conditional_rendering_ternary.py b/docs/examples/python/quick_start/conditional_rendering_ternary.py new file mode 100644 index 000000000..2490cb5f9 --- /dev/null +++ b/docs/examples/python/quick_start/conditional_rendering_ternary.py @@ -0,0 +1,18 @@ +from reactpy import component, html + + +def admin_panel(): + return [] + + +def login_form(): + return [] + + +is_logged_in = True + + +# start +@component +def my_component(): + return html.div(admin_panel() if is_logged_in else login_form()) diff --git a/docs/examples/python/quick_start/creating_and_nesting_components.py b/docs/examples/python/quick_start/creating_and_nesting_components.py new file mode 100644 index 000000000..0841e9514 --- /dev/null +++ b/docs/examples/python/quick_start/creating_and_nesting_components.py @@ -0,0 +1,21 @@ +from reactpy import component, html + + +@component +def my_button(): + return html.button("I'm a button!") + + +@component +def my_app(): + return html.div( + html.h1("Welcome to my app"), + my_button(), + ) + + +# end +if __name__ == "__main__": + from reactpy import run + + run(my_app) diff --git a/docs/examples/python/quick_start/displaying_data.py b/docs/examples/python/quick_start/displaying_data.py new file mode 100644 index 000000000..3534fe29d --- /dev/null +++ b/docs/examples/python/quick_start/displaying_data.py @@ -0,0 +1,37 @@ +from reactpy import component, html + +user = { + "name": "Hedy Lamarr", + "image_url": "https://i.imgur.com/yXOvdOSs.jpg", + "image_size": 90, +} + + +@component +def profile(): + return html.div( + html.h3(user["name"]), + html.img( + { + "class_name": "avatar", + "src": user["image_url"], + "alt": f"Photo of {user['name']}", + "style": { + "width": user["image_size"], + "height": user["image_size"], + }, + } + ), + ) + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), profile()) + + run(styled_app) diff --git a/docs/examples/python/quick_start/my_app.py b/docs/examples/python/quick_start/my_app.py new file mode 100644 index 000000000..1616d54d1 --- /dev/null +++ b/docs/examples/python/quick_start/my_app.py @@ -0,0 +1,12 @@ +from reactpy import component, html + +from .my_button import my_button + + +# start +@component +def my_app(): + return html.div( + html.h1("Welcome to my app"), + my_button(), + ) diff --git a/docs/examples/python/quick_start/my_button.py b/docs/examples/python/quick_start/my_button.py new file mode 100644 index 000000000..0016632ca --- /dev/null +++ b/docs/examples/python/quick_start/my_button.py @@ -0,0 +1,7 @@ +from reactpy import component, html + + +# start +@component +def my_button(): + return html.button("I'm a button!") diff --git a/docs/examples/python/quick_start/rendering_lists.py b/docs/examples/python/quick_start/rendering_lists.py new file mode 100644 index 000000000..35ec3e069 --- /dev/null +++ b/docs/examples/python/quick_start/rendering_lists.py @@ -0,0 +1,30 @@ +from reactpy import component, html + +products = [ + {"title": "Cabbage", "is_fruit": False, "id": 1}, + {"title": "Garlic", "is_fruit": False, "id": 2}, + {"title": "Apple", "is_fruit": True, "id": 3}, +] + + +@component +def shopping_list(): + list_items = [ + html.li( + { + "key": product["id"], + "style": {"color": "magenta" if product["is_fruit"] else "darkgreen"}, + }, + product["title"], + ) + for product in products + ] + + return html.ul(list_items) + + +# end +if __name__ == "__main__": + from reactpy import run + + run(shopping_list) diff --git a/docs/examples/python/quick_start/rendering_lists_list_items.py b/docs/examples/python/quick_start/rendering_lists_list_items.py new file mode 100644 index 000000000..43e108f36 --- /dev/null +++ b/docs/examples/python/quick_start/rendering_lists_list_items.py @@ -0,0 +1,6 @@ +from reactpy import html + +from .rendering_lists_products import products + +# start +list_items = [html.li({"key": product["id"]}, product["title"]) for product in products] diff --git a/docs/examples/python/quick_start/rendering_lists_products.py b/docs/examples/python/quick_start/rendering_lists_products.py new file mode 100644 index 000000000..c2d6a5e31 --- /dev/null +++ b/docs/examples/python/quick_start/rendering_lists_products.py @@ -0,0 +1,5 @@ +products = [ + {"title": "Cabbage", "id": 1}, + {"title": "Garlic", "id": 2}, + {"title": "Apple", "id": 3}, +] diff --git a/docs/examples/python/quick_start/responding_to_events.py b/docs/examples/python/quick_start/responding_to_events.py new file mode 100644 index 000000000..c893353cf --- /dev/null +++ b/docs/examples/python/quick_start/responding_to_events.py @@ -0,0 +1,13 @@ +from reactpy import component, html + + +# start +@component +def my_button(): + def handle_click(event): + print("You clicked me!") + + return html.button( + {"on_click": handle_click}, + "Click me", + ) diff --git a/docs/examples/python/quick_start/sharing_data_between_components.py b/docs/examples/python/quick_start/sharing_data_between_components.py new file mode 100644 index 000000000..b256e6ecc --- /dev/null +++ b/docs/examples/python/quick_start/sharing_data_between_components.py @@ -0,0 +1,32 @@ +from reactpy import component, html, use_state + + +@component +def my_app(): + count, set_count = use_state(0) + + def handle_click(event): + set_count(count + 1) + + return html.div( + html.h1("Counters that update together"), + my_button(count, handle_click), + my_button(count, handle_click), + ) + + +@component +def my_button(count, on_click): + return html.button({"on_click": on_click}, f"Clicked {count} times") + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), my_app()) + + run(styled_app) diff --git a/docs/examples/python/quick_start/sharing_data_between_components_button.py b/docs/examples/python/quick_start/sharing_data_between_components_button.py new file mode 100644 index 000000000..b96dadfa6 --- /dev/null +++ b/docs/examples/python/quick_start/sharing_data_between_components_button.py @@ -0,0 +1,7 @@ +from reactpy import component, html + + +# start +@component +def my_button(count, on_click): + return html.button({"on_click": on_click}, f"Clicked {count} times") diff --git a/docs/examples/python/quick_start/sharing_data_between_components_move_state.py b/docs/examples/python/quick_start/sharing_data_between_components_move_state.py new file mode 100644 index 000000000..a3c6126c2 --- /dev/null +++ b/docs/examples/python/quick_start/sharing_data_between_components_move_state.py @@ -0,0 +1,20 @@ +from reactpy import component, html, use_state + +# start +@component +def my_app(): + count, set_count = use_state(0) + + def handle_click(event): + set_count(count + 1) + + return html.div( + html.h1("Counters that update separately"), + my_button(), + my_button(), + ) + + +@component +def my_button(): + # ... we're moving code from here ... diff --git a/docs/examples/python/quick_start/sharing_data_between_components_props.py b/docs/examples/python/quick_start/sharing_data_between_components_props.py new file mode 100644 index 000000000..52294076a --- /dev/null +++ b/docs/examples/python/quick_start/sharing_data_between_components_props.py @@ -0,0 +1,22 @@ +from reactpy import component, html, use_state + + +# start +@component +def my_app(): + count, set_count = use_state(0) + + def handle_click(event): + set_count(count + 1) + + return html.div( + html.h1("Counters that update together"), + my_button(count, handle_click), + my_button(count, handle_click), + ) + # end + + +@component +def my_button(count, on_click): + ... diff --git a/docs/examples/python/quick_start/updating_the_screen.py b/docs/examples/python/quick_start/updating_the_screen.py new file mode 100644 index 000000000..1fc6cebcd --- /dev/null +++ b/docs/examples/python/quick_start/updating_the_screen.py @@ -0,0 +1,32 @@ +from reactpy import component, html, use_state + + +@component +def my_app(): + return html.div( + html.h1("Counters that update separately"), + my_button(), + my_button(), + ) + + +@component +def my_button(): + count, set_count = use_state(0) + + def handle_click(event): + set_count(count + 1) + + return html.button({"on_click": handle_click}, f"Clicked {count} times") + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), my_app()) + + run(styled_app) diff --git a/docs/examples/python/quick_start/updating_the_screen_event.py b/docs/examples/python/quick_start/updating_the_screen_event.py new file mode 100644 index 000000000..2829c481c --- /dev/null +++ b/docs/examples/python/quick_start/updating_the_screen_event.py @@ -0,0 +1,12 @@ +from reactpy import component, html, use_state + + +# start +@component +def my_button(): + count, set_count = use_state(0) + + def handle_click(event): + set_count(count + 1) + + return html.button({"on_click": handle_click}, f"Clicked {count} times") diff --git a/docs/examples/python/quick_start/updating_the_screen_use_state.py b/docs/examples/python/quick_start/updating_the_screen_use_state.py new file mode 100644 index 000000000..010487c33 --- /dev/null +++ b/docs/examples/python/quick_start/updating_the_screen_use_state.py @@ -0,0 +1,5 @@ +from reactpy import use_state + +# end + +use_state() diff --git a/docs/examples/python/quick_start/updating_the_screen_use_state_button.py b/docs/examples/python/quick_start/updating_the_screen_use_state_button.py new file mode 100644 index 000000000..c331ee6c9 --- /dev/null +++ b/docs/examples/python/quick_start/updating_the_screen_use_state_button.py @@ -0,0 +1,8 @@ +from reactpy import component, use_state + + +# start +@component +def my_button(): + count, set_count = use_state(0) + # ... diff --git a/docs/examples/python/responding_to_events/simple_button.py b/docs/examples/python/responding_to_events/simple_button.py new file mode 100644 index 000000000..7753b4a70 --- /dev/null +++ b/docs/examples/python/responding_to_events/simple_button.py @@ -0,0 +1,7 @@ +from reactpy import component, html + + +# start +@component +def button(): + return html.button("I don't do anything") diff --git a/docs/examples/python/responding_to_events/simple_button_event.py b/docs/examples/python/responding_to_events/simple_button_event.py new file mode 100644 index 000000000..292f3531c --- /dev/null +++ b/docs/examples/python/responding_to_events/simple_button_event.py @@ -0,0 +1,22 @@ +from reactpy import component, html + + +@component +def button(): + def handle_click(event): + print("You clicked me!") + + return html.button({"on_click": handle_click}, "Click me") + + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), button()) + + run(styled_app) diff --git a/docs/examples/python/start_a_new_react_project/configure_example.py b/docs/examples/python/start_a_new_react_project/configure_example.py new file mode 100644 index 000000000..c04a0e54d --- /dev/null +++ b/docs/examples/python/start_a_new_react_project/configure_example.py @@ -0,0 +1,6 @@ +from fastapi import FastAPI + +from reactpy.backend.fastapi import configure + +asgi_app = FastAPI() +configure(asgi_app) diff --git a/docs/examples/python/thinking_in_react/add_inverse_data_flow.py b/docs/examples/python/thinking_in_react/add_inverse_data_flow.py new file mode 100644 index 000000000..fdb7c79ad --- /dev/null +++ b/docs/examples/python/thinking_in_react/add_inverse_data_flow.py @@ -0,0 +1,120 @@ +from reactpy import component, html, use_state + + +@component +def filterable_product_table(products): + filter_text, set_filter_text = use_state("") + in_stock_only, set_in_stock_only = use_state(False) + + return html.div( + search_bar( + filter_text=filter_text, + in_stock_only=in_stock_only, + set_filter_text=set_filter_text, + set_in_stock_only=set_in_stock_only, + ), + product_table( + products=products, filter_text=filter_text, in_stock_only=in_stock_only + ), + ) + + +@component +def product_category_row(category): + return html.tr( + html.th({"colspan": 2}, category), + ) + + +@component +def product_row(product): + if product["stocked"]: + name = product["name"] + else: + name = html.span({"style": {"color": "red"}}, product["name"]) + + return html.tr( + html.td(name), + html.td(product["price"]), + ) + + +@component +def product_table(products, filter_text, in_stock_only): + rows = [] + last_category = None + + for product in products: + if filter_text.lower() not in product["name"].lower(): + continue + if in_stock_only and not product["stocked"]: + continue + if product["category"] != last_category: + rows.append( + product_category_row(product["category"], key=product["category"]) + ) + rows.append(product_row(product, key=product["name"])) + last_category = product["category"] + + return html.table( + html.thead( + html.tr( + html.th("Name"), + html.th("Price"), + ), + ), + html.tbody(rows), + ) + + +@component +def search_bar(filter_text, in_stock_only, set_filter_text, set_in_stock_only): + return html.form( + html.input( + { + "type": "text", + "value": filter_text, + "placeholder": "Search...", + "on_change": lambda event: set_filter_text(event["target"]["value"]), + } + ), + html.label( + html.input( + { + "type": "checkbox", + "checked": in_stock_only, + "on_change": lambda event: set_in_stock_only( + event["target"]["checked"] + ), + } + ), + "Only show products in stock", + ), + ) + + +PRODUCTS = [ + {"category": "Fruits", "price": "$1", "stocked": True, "name": "Apple"}, + {"category": "Fruits", "price": "$1", "stocked": True, "name": "Dragonfruit"}, + {"category": "Fruits", "price": "$2", "stocked": False, "name": "Passionfruit"}, + {"category": "Vegetables", "price": "$2", "stocked": True, "name": "Spinach"}, + {"category": "Vegetables", "price": "$4", "stocked": False, "name": "Pumpkin"}, + {"category": "Vegetables", "price": "$1", "stocked": True, "name": "Peas"}, +] + + +@component +def app(): + return filterable_product_table(PRODUCTS) + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), app()) + + run(styled_app) diff --git a/docs/examples/python/thinking_in_react/build_a_static_version_in_react.py b/docs/examples/python/thinking_in_react/build_a_static_version_in_react.py new file mode 100644 index 000000000..428406707 --- /dev/null +++ b/docs/examples/python/thinking_in_react/build_a_static_version_in_react.py @@ -0,0 +1,72 @@ +from reactpy import component, html + + +@component +def product_category_row(category): + return html.tr(html.th({"colSpan": "2"}, category)) + + +@component +def product_row(product): + if product["stocked"]: + name = product["name"] + else: + name = html.span({"style": {"color": "red"}}, product["name"]) + return html.tr(html.td(name), html.td(product["price"])) + + +@component +def product_table(products): + rows = [] + last_category = None + for product in products: + if product["category"] != last_category: + rows.append( + product_category_row(product["category"], key=product["category"]) + ) + rows.append(product_row(product, key=product["name"])) + last_category = product["category"] + + return html.table( + html.thead(html.tr(html.th("Name"), html.th("Price"))), html.tbody(rows) + ) + + +@component +def search_bar(): + return html.form( + html.input({"type": "text", "placeholder": "Search..."}), + html.label(html.input({"type": "checkbox"}), "Only show products in stock"), + ) + + +@component +def filterable_product_table(products): + return html.div(search_bar(), product_table(products)) + + +PRODUCTS = [ + {"category": "Fruits", "price": "$1", "stocked": True, "name": "Apple"}, + {"category": "Fruits", "price": "$1", "stocked": True, "name": "Dragonfruit"}, + {"category": "Fruits", "price": "$2", "stocked": False, "name": "Passionfruit"}, + {"category": "Vegetables", "price": "$2", "stocked": True, "name": "Spinach"}, + {"category": "Vegetables", "price": "$4", "stocked": False, "name": "Pumpkin"}, + {"category": "Vegetables", "price": "$1", "stocked": True, "name": "Peas"}, +] + + +@component +def app(): + return filterable_product_table(PRODUCTS) + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), app()) + + run(styled_app) diff --git a/docs/examples/python/thinking_in_react/error_example.py b/docs/examples/python/thinking_in_react/error_example.py new file mode 100644 index 000000000..e1ae45c3c --- /dev/null +++ b/docs/examples/python/thinking_in_react/error_example.py @@ -0,0 +1,19 @@ +from reactpy import component, html + + +# start +@component +def search_bar(filter_text, in_stock_only): + return html.form( + html.input( + { + "type": "text", + "value": filter_text, + "placeholder": "Search...", + } + ), + html.p( + html.input({"type": "checkbox", "checked": in_stock_only}), + "Only show products in stock", + ), + ) diff --git a/docs/examples/python/thinking_in_react/event_handlers.py b/docs/examples/python/thinking_in_react/event_handlers.py new file mode 100644 index 000000000..a97358c10 --- /dev/null +++ b/docs/examples/python/thinking_in_react/event_handlers.py @@ -0,0 +1,18 @@ +from reactpy import html + +filter_text = "" + + +def set_filter_text(value): + ... + + +# start +html.input( + { + "type": "text", + "value": filter_text, + "placeholder": "Search...", + "on_change": lambda event: set_filter_text(event["target"]["value"]), + } +) diff --git a/docs/examples/python/thinking_in_react/identify_where_your_state_should_live.py b/docs/examples/python/thinking_in_react/identify_where_your_state_should_live.py new file mode 100644 index 000000000..c201b6742 --- /dev/null +++ b/docs/examples/python/thinking_in_react/identify_where_your_state_should_live.py @@ -0,0 +1,100 @@ +from reactpy import component, html, use_state + + +@component +def filterable_product_table(products): + filter_text, set_filter_text = use_state("") + in_stock_only, set_in_stock_only = use_state(False) + + return html.div( + search_bar(filter_text=filter_text, in_stock_only=in_stock_only), + product_table( + products=products, filter_text=filter_text, in_stock_only=in_stock_only + ), + ) + + +@component +def product_category_row(category): + return html.tr( + html.th({"colspan": 2}, category), + ) + + +@component +def product_row(product): + if product["stocked"]: + name = product["name"] + else: + name = html.span({"style": {"color": "red"}}, product["name"]) + + return html.tr( + html.td(name), + html.td(product["price"]), + ) + + +@component +def product_table(products, filter_text, in_stock_only): + rows = [] + last_category = None + + for product in products: + if filter_text.lower() not in product["name"].lower(): + continue + if in_stock_only and not product["stocked"]: + continue + if product["category"] != last_category: + rows.append( + product_category_row(product["category"], key=product["category"]) + ) + rows.append(product_row(product, key=product["name"])) + last_category = product["category"] + + return html.table( + html.thead( + html.tr( + html.th("Name"), + html.th("Price"), + ), + ), + html.tbody(rows), + ) + + +@component +def search_bar(filter_text, in_stock_only): + return html.form( + html.input({"type": "text", "value": filter_text, "placeholder": "Search..."}), + html.label( + html.input({"type": "checkbox", "checked": in_stock_only}), + "Only show products in stock", + ), + ) + + +PRODUCTS = [ + {"category": "Fruits", "price": "$1", "stocked": True, "name": "Apple"}, + {"category": "Fruits", "price": "$1", "stocked": True, "name": "Dragonfruit"}, + {"category": "Fruits", "price": "$2", "stocked": False, "name": "Passionfruit"}, + {"category": "Vegetables", "price": "$2", "stocked": True, "name": "Spinach"}, + {"category": "Vegetables", "price": "$4", "stocked": False, "name": "Pumpkin"}, + {"category": "Vegetables", "price": "$1", "stocked": True, "name": "Peas"}, +] + + +@component +def app(): + return filterable_product_table(PRODUCTS) + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), app()) + + run(styled_app) diff --git a/docs/examples/python/thinking_in_react/set_state_props.py b/docs/examples/python/thinking_in_react/set_state_props.py new file mode 100644 index 000000000..bbd601416 --- /dev/null +++ b/docs/examples/python/thinking_in_react/set_state_props.py @@ -0,0 +1,32 @@ +# function filterable_product_table({ products }) { +# const [filter_text, set_filter_text] = use_state(''); +# const [in_stock_only, set_in_stock_only] = use_state(false); + +# return ( +#
+# + +from reactpy import component, hooks, html + + +def search_bar(**_kws): + ... + +# start +@component +def filterable_product_table(products): + filter_text, set_filter_text = hooks.use_state("") + in_stock_only, set_in_stock_only = hooks.use_state(False) + + return html.div( + search_bar( + filter_text=filter_text, + in_stock_only=in_stock_only, + set_filter_text=set_filter_text, + set_in_stock_only=set_in_stock_only + ) + ) diff --git a/docs/examples/python/thinking_in_react/use_state.py b/docs/examples/python/thinking_in_react/use_state.py new file mode 100644 index 000000000..437554974 --- /dev/null +++ b/docs/examples/python/thinking_in_react/use_state.py @@ -0,0 +1,8 @@ +from reactpy import component, use_state + + +# start +@component +def filterable_product_table(products): + filter_text, set_filter_text = use_state("") + in_stock_only, set_in_stock_only = use_state(False) diff --git a/docs/examples/python/thinking_in_react/use_state_with_components.py b/docs/examples/python/thinking_in_react/use_state_with_components.py new file mode 100644 index 000000000..2964929ea --- /dev/null +++ b/docs/examples/python/thinking_in_react/use_state_with_components.py @@ -0,0 +1,17 @@ +from reactpy import html + +filter_text = "" +in_stock_only = False +products = () + +def search_bar(**_kw): + ... + +def product_table(**_kw): + ... + +# start +html.div( + search_bar(filter_text=filter_text, in_stock_only=in_stock_only), + product_table(products=products, filter_text=filter_text, in_stock_only=in_stock_only), +) diff --git a/docs/examples/python/tutorial_tic_tac_toe/setup_for_the_tutorial.py b/docs/examples/python/tutorial_tic_tac_toe/setup_for_the_tutorial.py new file mode 100644 index 000000000..efca94195 --- /dev/null +++ b/docs/examples/python/tutorial_tic_tac_toe/setup_for_the_tutorial.py @@ -0,0 +1,6 @@ +from reactpy import component, html + +# start +@component +def square(): + return html.button({"class_name":"square"}, "X") diff --git a/docs/examples/python/tutorial_tic_tac_toe/tic_tac_toe.py b/docs/examples/python/tutorial_tic_tac_toe/tic_tac_toe.py new file mode 100644 index 000000000..eef970924 --- /dev/null +++ b/docs/examples/python/tutorial_tic_tac_toe/tic_tac_toe.py @@ -0,0 +1,127 @@ +from copy import deepcopy + +from reactpy import component, html, use_state + + +@component +def square(value, on_square_click): + return html.button( + {"className": "square", "on_click": on_square_click}, + value, + ) + + +@component +def board(x_is_next, squares, on_play): + def handle_click(i): + def handle_click_event(_event): + """ + Due to a quirk of Python, if your event handler needs args other than + `event`, you will need to create a wrapper function as seen above. + Ref: https://pylint.readthedocs.io/en/stable/user_guide/messages/warning/cell-var-from-loop.html + """ + if calculate_winner(squares) or squares[i]: + return + + next_squares = squares.copy() + next_squares[i] = "X" if x_is_next else "O" + on_play(next_squares) + + return handle_click_event + + winner = calculate_winner(squares) + status = ( + f"Winner: {winner}" if winner else "Next player: " + ("X" if x_is_next else "O") + ) + + return html._( + html.div({"className": "status"}, status), + html.div( + {"className": "board-row"}, + square(squares[0], handle_click(0)), + square(squares[1], handle_click(1)), + square(squares[2], handle_click(2)), + ), + html.div( + {"className": "board-row"}, + square(squares[3], handle_click(3)), + square(squares[4], handle_click(4)), + square(squares[5], handle_click(5)), + ), + html.div( + {"className": "board-row"}, + square(squares[6], handle_click(6)), + square(squares[7], handle_click(7)), + square(squares[8], handle_click(8)), + ), + ) + + +@component +def game(): + history, set_history = use_state([[None] * 9]) + current_move, set_current_move = use_state(0) + x_is_next = current_move % 2 == 0 + current_squares = history[current_move] + + def handle_play(next_squares): + next_history = deepcopy(history[: current_move + 1]) + next_history.append(next_squares) + set_history(next_history) + set_current_move(len(next_history) - 1) + + def jump_to(next_move): + return lambda _event: set_current_move(next_move) + + moves = [] + for move, _squares in enumerate(history): + description = f"Go to move #{move}" if move > 0 else "Go to game start" + + moves.append( + html.li( + {"key": move}, + html.button({"on_click": jump_to(move)}, description), + ) + ) + + return html.div( + {"className": "game"}, + html.div( + {"className": "game-board"}, + board(x_is_next, current_squares, handle_play), + ), + html.div({"className": "game-info"}, html.ol(moves)), + ) + + +def calculate_winner(squares): + lines = [ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + [0, 3, 6], + [1, 4, 7], + [2, 5, 8], + [0, 4, 8], + [2, 4, 6], + ] + for line in lines: + a, b, c = line + if not squares: + continue + if squares[a] and squares[a] == squares[b] and squares[a] == squares[c]: + return squares[a] + + return None + + +# end +if __name__ == "__main__": + from reactpy import run + from reactpy.utils import _read_docs_css + + @component + def styled_app(): + return html._(html.style(_read_docs_css()), game()) + + run(styled_app) diff --git a/docs/main.py b/docs/main.py deleted file mode 100644 index e3181f393..000000000 --- a/docs/main.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys - -from docs_app import dev, prod - -if __name__ == "__main__": - if len(sys.argv) == 1: - prod.main() - else: - dev.main() diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 000000000..e70aa10c8 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block content %} +{{ super() }} + +{% if git_page_authors %} +
+ + Authors: {{ git_page_authors | default('enable mkdocs-git-authors-plugin') }} + +
+{% endif %} +{% endblock %} diff --git a/docs/poetry.lock b/docs/poetry.lock deleted file mode 100644 index 8e1daef24..000000000 --- a/docs/poetry.lock +++ /dev/null @@ -1,2269 +0,0 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. - -[[package]] -name = "aiofiles" -version = "23.1.0" -description = "File support for asyncio." -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "aiofiles-23.1.0-py3-none-any.whl", hash = "sha256:9312414ae06472eb6f1d163f555e466a23aed1c8f60c30cccf7121dba2e53eb2"}, - {file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"}, -] - -[[package]] -name = "alabaster" -version = "0.7.13" -description = "A configurable sidebar-enabled Sphinx theme" -optional = false -python-versions = ">=3.6" -files = [ - {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, - {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, -] - -[[package]] -name = "anyio" -version = "3.7.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.7" -files = [ - {file = "anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0"}, - {file = "anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce"}, -] - -[package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" - -[package.extras] -doc = ["Sphinx (>=6.1.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] - -[[package]] -name = "asgiref" -version = "3.7.2" -description = "ASGI specs, helper code, and adapters" -optional = false -python-versions = ">=3.7" -files = [ - {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, - {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} - -[package.extras] -tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] - -[[package]] -name = "babel" -version = "2.12.1" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, -] - -[[package]] -name = "beautifulsoup4" -version = "4.12.2" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "certifi" -version = "2023.5.7" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, - {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.1.0" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, - {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, - {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, - {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, - {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, - {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, - {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, -] - -[[package]] -name = "click" -version = "8.1.3" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "colorlog" -version = "6.7.0" -description = "Add colours to the output of Python's logging module." -optional = false -python-versions = ">=3.6" -files = [ - {file = "colorlog-6.7.0-py2.py3-none-any.whl", hash = "sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662"}, - {file = "colorlog-6.7.0.tar.gz", hash = "sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -development = ["black", "flake8", "mypy", "pytest", "types-colorama"] - -[[package]] -name = "contourpy" -version = "1.0.7" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false -python-versions = ">=3.8" -files = [ - {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"}, - {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"}, - {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"}, - {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"}, - {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"}, - {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"}, - {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"}, - {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"}, - {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"}, - {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"}, - {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"}, - {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"}, - {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"}, - {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"}, - {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"}, - {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"}, - {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"}, - {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"}, - {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"}, - {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"}, - {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"}, - {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"}, - {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"}, - {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"}, - {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"}, -] - -[package.dependencies] -numpy = ">=1.16" - -[package.extras] -bokeh = ["bokeh", "chromedriver", "selenium"] -docs = ["furo", "sphinx-copybutton"] -mypy = ["contourpy[bokeh]", "docutils-stubs", "mypy (==0.991)", "types-Pillow"] -test = ["Pillow", "matplotlib", "pytest"] -test-no-images = ["pytest"] - -[[package]] -name = "cycler" -version = "0.11.0" -description = "Composable style cycles" -optional = false -python-versions = ">=3.6" -files = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, -] - -[[package]] -name = "docutils" -version = "0.17.1" -description = "Docutils -- Python Documentation Utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.1.1" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, - {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "fastapi" -version = "0.96.0" -description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -optional = false -python-versions = ">=3.7" -files = [ - {file = "fastapi-0.96.0-py3-none-any.whl", hash = "sha256:b8e11fe81e81eab4e1504209917338e0b80f783878a42c2b99467e5e1019a1e9"}, - {file = "fastapi-0.96.0.tar.gz", hash = "sha256:71232d47c2787446991c81c41c249f8a16238d52d779c0e6b43927d3773dbe3c"}, -] - -[package.dependencies] -pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" -starlette = ">=0.27.0,<0.28.0" - -[package.extras] -all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>=0.12.0,<0.21.0)"] -doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer-cli (>=0.0.13,<0.0.14)", "typer[all] (>=0.6.1,<0.8.0)"] -test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.7)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.7.0.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"] - -[[package]] -name = "fastjsonschema" -version = "2.17.1" -description = "Fastest Python implementation of JSON schema" -optional = false -python-versions = "*" -files = [ - {file = "fastjsonschema-2.17.1-py3-none-any.whl", hash = "sha256:4b90b252628ca695280924d863fe37234eebadc29c5360d322571233dc9746e0"}, - {file = "fastjsonschema-2.17.1.tar.gz", hash = "sha256:f4eeb8a77cef54861dbf7424ac8ce71306f12cbb086c45131bcba2c6a4f726e3"}, -] - -[package.extras] -devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] - -[[package]] -name = "flask" -version = "2.1.3" -description = "A simple framework for building complex web applications." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Flask-2.1.3-py3-none-any.whl", hash = "sha256:9013281a7402ad527f8fd56375164f3aa021ecfaff89bfe3825346c24f87e04c"}, - {file = "Flask-2.1.3.tar.gz", hash = "sha256:15972e5017df0575c3d6c090ba168b6db90259e620ac8d7ea813a396bad5b6cb"}, -] - -[package.dependencies] -click = ">=8.0" -importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} -itsdangerous = ">=2.0" -Jinja2 = ">=3.0" -Werkzeug = ">=2.0" - -[package.extras] -async = ["asgiref (>=3.2)"] -dotenv = ["python-dotenv"] - -[[package]] -name = "flask-cors" -version = "3.0.10" -description = "A Flask extension adding a decorator for CORS support" -optional = false -python-versions = "*" -files = [ - {file = "Flask-Cors-3.0.10.tar.gz", hash = "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"}, - {file = "Flask_Cors-3.0.10-py2.py3-none-any.whl", hash = "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438"}, -] - -[package.dependencies] -Flask = ">=0.9" -Six = "*" - -[[package]] -name = "flask-sock" -version = "0.6.0" -description = "WebSocket support for Flask" -optional = false -python-versions = ">=3.6" -files = [ - {file = "flask-sock-0.6.0.tar.gz", hash = "sha256:435cf81bb497ac7622cd1dda554fbfa3e369e629daea0a1d21b73a24f1bd6229"}, - {file = "flask_sock-0.6.0-py3-none-any.whl", hash = "sha256:593fffb186928080a5b5b03d717efc56dac2d5ed690ce6bfff333b3597a2f518"}, -] - -[package.dependencies] -flask = ">=2" -simple-websocket = ">=0.5.1" - -[[package]] -name = "fonttools" -version = "4.39.4" -description = "Tools to manipulate font files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fonttools-4.39.4-py3-none-any.whl", hash = "sha256:106caf6167c4597556b31a8d9175a3fdc0356fdcd70ab19973c3b0d4c893c461"}, - {file = "fonttools-4.39.4.zip", hash = "sha256:dba8d7cdb8e2bac1b3da28c5ed5960de09e59a2fe7e63bb73f5a59e57b0430d2"}, -] - -[package.extras] -all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres", "scipy"] -lxml = ["lxml (>=4.0,<5)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.0.0)"] -woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] - -[[package]] -name = "furo" -version = "2022.4.7" -description = "A clean customisable Sphinx documentation theme." -optional = false -python-versions = ">=3.6" -files = [ - {file = "furo-2022.4.7-py3-none-any.whl", hash = "sha256:7f3e3d2fb977483590f8ecb2c2cd511bd82661b79c18efb24de9558bc9cdf2d7"}, - {file = "furo-2022.4.7.tar.gz", hash = "sha256:96204ab7cd047e4b6c523996e0279c4c629a8fc31f4f109b2efd470c17f49c80"}, -] - -[package.dependencies] -beautifulsoup4 = "*" -pygments = ">=2.7,<3.0" -sphinx = ">=4.0,<5.0" - -[[package]] -name = "greenlet" -version = "2.0.2" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, - {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, - {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, - {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, - {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, - {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, - {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, - {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, - {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, - {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, - {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, - {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, - {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, - {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, - {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, - {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, - {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, - {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, - {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, - {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, - {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, - {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, - {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, - {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, - {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, - {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] -test = ["objgraph", "psutil"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "html5tagger" -version = "1.3.0" -description = "Pythonic HTML generation/templating (no template files)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "html5tagger-1.3.0-py3-none-any.whl", hash = "sha256:ce14313515edffec8ed8a36c5890d023922641171b4e6e5774ad1a74998f5351"}, - {file = "html5tagger-1.3.0.tar.gz", hash = "sha256:84fa3dfb49e5c83b79bbd856ab7b1de8e2311c3bb46a8be925f119e3880a8da9"}, -] - -[[package]] -name = "httptools" -version = "0.5.0" -description = "A collection of framework independent HTTP protocol utils." -optional = false -python-versions = ">=3.5.0" -files = [ - {file = "httptools-0.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8f470c79061599a126d74385623ff4744c4e0f4a0997a353a44923c0b561ee51"}, - {file = "httptools-0.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e90491a4d77d0cb82e0e7a9cb35d86284c677402e4ce7ba6b448ccc7325c5421"}, - {file = "httptools-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1d2357f791b12d86faced7b5736dea9ef4f5ecdc6c3f253e445ee82da579449"}, - {file = "httptools-0.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f90cd6fd97c9a1b7fe9215e60c3bd97336742a0857f00a4cb31547bc22560c2"}, - {file = "httptools-0.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5230a99e724a1bdbbf236a1b58d6e8504b912b0552721c7c6b8570925ee0ccde"}, - {file = "httptools-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3a47a34f6015dd52c9eb629c0f5a8a5193e47bf2a12d9a3194d231eaf1bc451a"}, - {file = "httptools-0.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:24bb4bb8ac3882f90aa95403a1cb48465de877e2d5298ad6ddcfdebec060787d"}, - {file = "httptools-0.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e67d4f8734f8054d2c4858570cc4b233bf753f56e85217de4dfb2495904cf02e"}, - {file = "httptools-0.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7e5eefc58d20e4c2da82c78d91b2906f1a947ef42bd668db05f4ab4201a99f49"}, - {file = "httptools-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0297822cea9f90a38df29f48e40b42ac3d48a28637368f3ec6d15eebefd182f9"}, - {file = "httptools-0.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:557be7fbf2bfa4a2ec65192c254e151684545ebab45eca5d50477d562c40f986"}, - {file = "httptools-0.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:54465401dbbec9a6a42cf737627fb0f014d50dc7365a6b6cd57753f151a86ff0"}, - {file = "httptools-0.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4d9ebac23d2de960726ce45f49d70eb5466725c0087a078866043dad115f850f"}, - {file = "httptools-0.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:e8a34e4c0ab7b1ca17b8763613783e2458e77938092c18ac919420ab8655c8c1"}, - {file = "httptools-0.5.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f659d7a48401158c59933904040085c200b4be631cb5f23a7d561fbae593ec1f"}, - {file = "httptools-0.5.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef1616b3ba965cd68e6f759eeb5d34fbf596a79e84215eeceebf34ba3f61fdc7"}, - {file = "httptools-0.5.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3625a55886257755cb15194efbf209584754e31d336e09e2ffe0685a76cb4b60"}, - {file = "httptools-0.5.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:72ad589ba5e4a87e1d404cc1cb1b5780bfcb16e2aec957b88ce15fe879cc08ca"}, - {file = "httptools-0.5.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:850fec36c48df5a790aa735417dca8ce7d4b48d59b3ebd6f83e88a8125cde324"}, - {file = "httptools-0.5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f222e1e9d3f13b68ff8a835574eda02e67277d51631d69d7cf7f8e07df678c86"}, - {file = "httptools-0.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3cb8acf8f951363b617a8420768a9f249099b92e703c052f9a51b66342eea89b"}, - {file = "httptools-0.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550059885dc9c19a072ca6d6735739d879be3b5959ec218ba3e013fd2255a11b"}, - {file = "httptools-0.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a04fe458a4597aa559b79c7f48fe3dceabef0f69f562daf5c5e926b153817281"}, - {file = "httptools-0.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d0c1044bce274ec6711f0770fd2d5544fe392591d204c68328e60a46f88843b"}, - {file = "httptools-0.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c6eeefd4435055a8ebb6c5cc36111b8591c192c56a95b45fe2af22d9881eee25"}, - {file = "httptools-0.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5b65be160adcd9de7a7e6413a4966665756e263f0d5ddeffde277ffeee0576a5"}, - {file = "httptools-0.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fe9c766a0c35b7e3d6b6939393c8dfdd5da3ac5dec7f971ec9134f284c6c36d6"}, - {file = "httptools-0.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85b392aba273566c3d5596a0a490978c085b79700814fb22bfd537d381dd230c"}, - {file = "httptools-0.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5e3088f4ed33947e16fd865b8200f9cfae1144f41b64a8cf19b599508e096bc"}, - {file = "httptools-0.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c2a56b6aad7cc8f5551d8e04ff5a319d203f9d870398b94702300de50190f63"}, - {file = "httptools-0.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9b571b281a19762adb3f48a7731f6842f920fa71108aff9be49888320ac3e24d"}, - {file = "httptools-0.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa47ffcf70ba6f7848349b8a6f9b481ee0f7637931d91a9860a1838bfc586901"}, - {file = "httptools-0.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:bede7ee075e54b9a5bde695b4fc8f569f30185891796b2e4e09e2226801d09bd"}, - {file = "httptools-0.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:64eba6f168803a7469866a9c9b5263a7463fa8b7a25b35e547492aa7322036b6"}, - {file = "httptools-0.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4b098e4bb1174096a93f48f6193e7d9aa7071506a5877da09a783509ca5fff42"}, - {file = "httptools-0.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9423a2de923820c7e82e18980b937893f4aa8251c43684fa1772e341f6e06887"}, - {file = "httptools-0.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca1b7becf7d9d3ccdbb2f038f665c0f4857e08e1d8481cbcc1a86a0afcfb62b2"}, - {file = "httptools-0.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:50d4613025f15f4b11f1c54bbed4761c0020f7f921b95143ad6d58c151198142"}, - {file = "httptools-0.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8ffce9d81c825ac1deaa13bc9694c0562e2840a48ba21cfc9f3b4c922c16f372"}, - {file = "httptools-0.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:1af91b3650ce518d226466f30bbba5b6376dbd3ddb1b2be8b0658c6799dd450b"}, - {file = "httptools-0.5.0.tar.gz", hash = "sha256:295874861c173f9101960bba332429bb77ed4dcd8cdf5cee9922eb00e4f6bc09"}, -] - -[package.extras] -test = ["Cython (>=0.29.24,<0.30.0)"] - -[[package]] -name = "idna" -version = "3.4" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] - -[[package]] -name = "imagesize" -version = "1.4.1" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, - {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, -] - -[[package]] -name = "importlib-metadata" -version = "6.6.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, - {file = "importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] - -[[package]] -name = "importlib-resources" -version = "5.12.0" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - -[[package]] -name = "itsdangerous" -version = "2.1.2" -description = "Safely pass data to untrusted environments and back." -optional = false -python-versions = ">=3.7" -files = [ - {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, - {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, -] - -[[package]] -name = "jinja2" -version = "3.1.2" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jsonpatch" -version = "1.32" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "jsonpatch-1.32-py2.py3-none-any.whl", hash = "sha256:26ac385719ac9f54df8a2f0827bb8253aa3ea8ab7b3368457bcdb8c14595a397"}, - {file = "jsonpatch-1.32.tar.gz", hash = "sha256:b6ddfe6c3db30d81a96aaeceb6baf916094ffa23d7dd5fa2c13e13f8b6e600c2"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "2.3" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "jsonpointer-2.3-py2.py3-none-any.whl", hash = "sha256:51801e558539b4e9cd268638c078c6c5746c9ac96bc38152d443400e4f3793e9"}, - {file = "jsonpointer-2.3.tar.gz", hash = "sha256:97cba51526c829282218feb99dab1b1e6bdf8efd1c43dc9d57be093c0d69c99a"}, -] - -[[package]] -name = "kiwisolver" -version = "1.4.4" -description = "A fast implementation of the Cassowary constraint solver" -optional = false -python-versions = ">=3.7" -files = [ - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, - {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, - {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, - {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"}, - {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"}, - {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"}, - {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"}, - {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, - {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, - {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, - {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, - {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, - {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, - {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, - {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"}, - {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"}, - {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"}, - {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, -] - -[[package]] -name = "livereload" -version = "2.6.3" -description = "Python LiveReload is an awesome tool for web developers" -optional = false -python-versions = "*" -files = [ - {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, - {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, -] - -[package.dependencies] -six = "*" -tornado = {version = "*", markers = "python_version > \"2.7\""} - -[[package]] -name = "lxml" -version = "4.9.2" -description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" -files = [ - {file = "lxml-4.9.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2"}, - {file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892"}, - {file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a"}, - {file = "lxml-4.9.2-cp27-cp27m-win32.whl", hash = "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de"}, - {file = "lxml-4.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3"}, - {file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50"}, - {file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975"}, - {file = "lxml-4.9.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c"}, - {file = "lxml-4.9.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a"}, - {file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4"}, - {file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4"}, - {file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7"}, - {file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184"}, - {file = "lxml-4.9.2-cp310-cp310-win32.whl", hash = "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda"}, - {file = "lxml-4.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab"}, - {file = "lxml-4.9.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9"}, - {file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf"}, - {file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380"}, - {file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92"}, - {file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1"}, - {file = "lxml-4.9.2-cp311-cp311-win32.whl", hash = "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33"}, - {file = "lxml-4.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd"}, - {file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0"}, - {file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e"}, - {file = "lxml-4.9.2-cp35-cp35m-win32.whl", hash = "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df"}, - {file = "lxml-4.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5"}, - {file = "lxml-4.9.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1"}, - {file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e"}, - {file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74"}, - {file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38"}, - {file = "lxml-4.9.2-cp36-cp36m-win32.whl", hash = "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5"}, - {file = "lxml-4.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3"}, - {file = "lxml-4.9.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894"}, - {file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45"}, - {file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e"}, - {file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b"}, - {file = "lxml-4.9.2-cp37-cp37m-win32.whl", hash = "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe"}, - {file = "lxml-4.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9"}, - {file = "lxml-4.9.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03"}, - {file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c"}, - {file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f"}, - {file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457"}, - {file = "lxml-4.9.2-cp38-cp38-win32.whl", hash = "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b"}, - {file = "lxml-4.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7"}, - {file = "lxml-4.9.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947"}, - {file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5"}, - {file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5"}, - {file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2"}, - {file = "lxml-4.9.2-cp39-cp39-win32.whl", hash = "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1"}, - {file = "lxml-4.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f"}, - {file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c"}, - {file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f"}, - {file = "lxml-4.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7"}, - {file = "lxml-4.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409"}, - {file = "lxml-4.9.2.tar.gz", hash = "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67"}, -] - -[package.extras] -cssselect = ["cssselect (>=0.7)"] -html5 = ["html5lib"] -htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=0.29.7)"] - -[[package]] -name = "markupsafe" -version = "2.0.1" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.6" -files = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, -] - -[[package]] -name = "matplotlib" -version = "3.7.1" -description = "Python plotting package" -optional = false -python-versions = ">=3.8" -files = [ - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"}, - {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"}, - {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"}, - {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"}, - {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"}, - {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"}, - {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"}, - {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"}, - {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"}, - {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"}, - {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"}, - {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"}, - {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"}, - {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"}, - {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"}, - {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"}, - {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"}, - {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"}, - {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"}, - {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""} -kiwisolver = ">=1.0.1" -numpy = ">=1.20" -packaging = ">=20.0" -pillow = ">=6.2.0" -pyparsing = ">=2.3.1" -python-dateutil = ">=2.7" - -[[package]] -name = "multidict" -version = "6.0.4" -description = "multidict implementation" -optional = false -python-versions = ">=3.7" -files = [ - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, - {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, - {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, - {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, - {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, - {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, - {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, - {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, - {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, - {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, - {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, - {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, - {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, -] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "numpy" -version = "1.24.3" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, - {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, - {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, - {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, - {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, - {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, - {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, - {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, - {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, - {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, - {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, - {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, - {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, - {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, - {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, - {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, - {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, - {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, - {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, -] - -[[package]] -name = "packaging" -version = "23.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, -] - -[[package]] -name = "pillow" -version = "9.5.0" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Pillow-9.5.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:ace6ca218308447b9077c14ea4ef381ba0b67ee78d64046b3f19cf4e1139ad16"}, - {file = "Pillow-9.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d3d403753c9d5adc04d4694d35cf0391f0f3d57c8e0030aac09d7678fa8030aa"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba1b81ee69573fe7124881762bb4cd2e4b6ed9dd28c9c60a632902fe8db8b38"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe7e1c262d3392afcf5071df9afa574544f28eac825284596ac6db56e6d11062"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f36397bf3f7d7c6a3abdea815ecf6fd14e7fcd4418ab24bae01008d8d8ca15e"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:252a03f1bdddce077eff2354c3861bf437c892fb1832f75ce813ee94347aa9b5"}, - {file = "Pillow-9.5.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:85ec677246533e27770b0de5cf0f9d6e4ec0c212a1f89dfc941b64b21226009d"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b416f03d37d27290cb93597335a2f85ed446731200705b22bb927405320de903"}, - {file = "Pillow-9.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1781a624c229cb35a2ac31cc4a77e28cafc8900733a864870c49bfeedacd106a"}, - {file = "Pillow-9.5.0-cp310-cp310-win32.whl", hash = "sha256:8507eda3cd0608a1f94f58c64817e83ec12fa93a9436938b191b80d9e4c0fc44"}, - {file = "Pillow-9.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d3c6b54e304c60c4181da1c9dadf83e4a54fd266a99c70ba646a9baa626819eb"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:7ec6f6ce99dab90b52da21cf0dc519e21095e332ff3b399a357c187b1a5eee32"}, - {file = "Pillow-9.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:560737e70cb9c6255d6dcba3de6578a9e2ec4b573659943a5e7e4af13f298f5c"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96e88745a55b88a7c64fa49bceff363a1a27d9a64e04019c2281049444a571e3"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9c206c29b46cfd343ea7cdfe1232443072bbb270d6a46f59c259460db76779a"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfcc2c53c06f2ccb8976fb5c71d448bdd0a07d26d8e07e321c103416444c7ad1"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:a0f9bb6c80e6efcde93ffc51256d5cfb2155ff8f78292f074f60f9e70b942d99"}, - {file = "Pillow-9.5.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8d935f924bbab8f0a9a28404422da8af4904e36d5c33fc6f677e4c4485515625"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fed1e1cf6a42577953abbe8e6cf2fe2f566daebde7c34724ec8803c4c0cda579"}, - {file = "Pillow-9.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c1170d6b195555644f0616fd6ed929dfcf6333b8675fcca044ae5ab110ded296"}, - {file = "Pillow-9.5.0-cp311-cp311-win32.whl", hash = "sha256:54f7102ad31a3de5666827526e248c3530b3a33539dbda27c6843d19d72644ec"}, - {file = "Pillow-9.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:cfa4561277f677ecf651e2b22dc43e8f5368b74a25a8f7d1d4a3a243e573f2d4"}, - {file = "Pillow-9.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:965e4a05ef364e7b973dd17fc765f42233415974d773e82144c9bbaaaea5d089"}, - {file = "Pillow-9.5.0-cp312-cp312-win32.whl", hash = "sha256:22baf0c3cf0c7f26e82d6e1adf118027afb325e703922c8dfc1d5d0156bb2eeb"}, - {file = "Pillow-9.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:432b975c009cf649420615388561c0ce7cc31ce9b2e374db659ee4f7d57a1f8b"}, - {file = "Pillow-9.5.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5d4ebf8e1db4441a55c509c4baa7a0587a0210f7cd25fcfe74dbbce7a4bd1906"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:375f6e5ee9620a271acb6820b3d1e94ffa8e741c0601db4c0c4d3cb0a9c224bf"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99eb6cafb6ba90e436684e08dad8be1637efb71c4f2180ee6b8f940739406e78"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dfaaf10b6172697b9bceb9a3bd7b951819d1ca339a5ef294d1f1ac6d7f63270"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:763782b2e03e45e2c77d7779875f4432e25121ef002a41829d8868700d119392"}, - {file = "Pillow-9.5.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:35f6e77122a0c0762268216315bf239cf52b88865bba522999dc38f1c52b9b47"}, - {file = "Pillow-9.5.0-cp37-cp37m-win32.whl", hash = "sha256:aca1c196f407ec7cf04dcbb15d19a43c507a81f7ffc45b690899d6a76ac9fda7"}, - {file = "Pillow-9.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322724c0032af6692456cd6ed554bb85f8149214d97398bb80613b04e33769f6"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:a0aa9417994d91301056f3d0038af1199eb7adc86e646a36b9e050b06f526597"}, - {file = "Pillow-9.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8286396b351785801a976b1e85ea88e937712ee2c3ac653710a4a57a8da5d9c"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c830a02caeb789633863b466b9de10c015bded434deb3ec87c768e53752ad22a"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbd359831c1657d69bb81f0db962905ee05e5e9451913b18b831febfe0519082"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc330c3370a81bbf3f88557097d1ea26cd8b019d6433aa59f71195f5ddebbf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:7002d0797a3e4193c7cdee3198d7c14f92c0836d6b4a3f3046a64bd1ce8df2bf"}, - {file = "Pillow-9.5.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:229e2c79c00e85989a34b5981a2b67aa079fd08c903f0aaead522a1d68d79e51"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9adf58f5d64e474bed00d69bcd86ec4bcaa4123bfa70a65ce72e424bfb88ed96"}, - {file = "Pillow-9.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:662da1f3f89a302cc22faa9f14a262c2e3951f9dbc9617609a47521c69dd9f8f"}, - {file = "Pillow-9.5.0-cp38-cp38-win32.whl", hash = "sha256:6608ff3bf781eee0cd14d0901a2b9cc3d3834516532e3bd673a0a204dc8615fc"}, - {file = "Pillow-9.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:e49eb4e95ff6fd7c0c402508894b1ef0e01b99a44320ba7d8ecbabefddcc5569"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:482877592e927fd263028c105b36272398e3e1be3269efda09f6ba21fd83ec66"}, - {file = "Pillow-9.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ded42b9ad70e5f1754fb7c2e2d6465a9c842e41d178f262e08b8c85ed8a1d8e"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c446d2245ba29820d405315083d55299a796695d747efceb5717a8b450324115"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aca1152d93dcc27dc55395604dcfc55bed5f25ef4c98716a928bacba90d33a3"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:608488bdcbdb4ba7837461442b90ea6f3079397ddc968c31265c1e056964f1ef"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:60037a8db8750e474af7ffc9faa9b5859e6c6d0a50e55c45576bf28be7419705"}, - {file = "Pillow-9.5.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:07999f5834bdc404c442146942a2ecadd1cb6292f5229f4ed3b31e0a108746b1"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a127ae76092974abfbfa38ca2d12cbeddcdeac0fb71f9627cc1135bedaf9d51a"}, - {file = "Pillow-9.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:489f8389261e5ed43ac8ff7b453162af39c3e8abd730af8363587ba64bb2e865"}, - {file = "Pillow-9.5.0-cp39-cp39-win32.whl", hash = "sha256:9b1af95c3a967bf1da94f253e56b6286b50af23392a886720f563c547e48e964"}, - {file = "Pillow-9.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:77165c4a5e7d5a284f10a6efaa39a0ae8ba839da344f20b111d62cc932fa4e5d"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:833b86a98e0ede388fa29363159c9b1a294b0905b5128baf01db683672f230f5"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aaf305d6d40bd9632198c766fb64f0c1a83ca5b667f16c1e79e1661ab5060140"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0852ddb76d85f127c135b6dd1f0bb88dbb9ee990d2cd9aa9e28526c93e794fba"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:91ec6fe47b5eb5a9968c79ad9ed78c342b1f97a091677ba0e012701add857829"}, - {file = "Pillow-9.5.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb841572862f629b99725ebaec3287fc6d275be9b14443ea746c1dd325053cbd"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c380b27d041209b849ed246b111b7c166ba36d7933ec6e41175fd15ab9eb1572"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c9af5a3b406a50e313467e3565fc99929717f780164fe6fbb7704edba0cebbe"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5671583eab84af046a397d6d0ba25343c00cd50bce03787948e0fff01d4fd9b1"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:84a6f19ce086c1bf894644b43cd129702f781ba5751ca8572f08aa40ef0ab7b7"}, - {file = "Pillow-9.5.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1e7723bd90ef94eda669a3c2c19d549874dd5badaeefabefd26053304abe5799"}, - {file = "Pillow-9.5.0.tar.gz", hash = "sha256:bf548479d336726d7a0eceb6e767e179fbde37833ae42794602631a070d630f1"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "playwright" -version = "1.34.0" -description = "A high-level API to automate web browsers" -optional = false -python-versions = ">=3.7" -files = [ - {file = "playwright-1.34.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:69bb9b3296e366a23a99277b4c7673cb54ce71a3f5d630f114f7701b61f98f25"}, - {file = "playwright-1.34.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:402d946631c8458436e099d7731bbf54cf79c9e62e3acae0ea8421e72616926b"}, - {file = "playwright-1.34.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:462251cda0fcbb273497d357dbe14b11e43ebceb0bac9b892beda041ff209aa9"}, - {file = "playwright-1.34.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:a8ba124ea302596a03a66993cd500484fb255cbc10fe0757fa4d49f974267a80"}, - {file = "playwright-1.34.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf0cb6aac49d24335fe361868aea72b11f276a95e7809f1a5d1c69b4120c46ac"}, - {file = "playwright-1.34.0-py3-none-win32.whl", hash = "sha256:c50fef189d87243cc09ae0feb8e417fbe434359ccbcc863fb19ba06d46d31c33"}, - {file = "playwright-1.34.0-py3-none-win_amd64.whl", hash = "sha256:42e16c930e1e910461f4c551a72fc1b900f37124431bf2b6a6d9ddae70042db4"}, -] - -[package.dependencies] -greenlet = "2.0.2" -pyee = "9.0.4" - -[[package]] -name = "pydantic" -version = "1.10.8" -description = "Data validation and settings management using python type hints" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pydantic-1.10.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1243d28e9b05003a89d72e7915fdb26ffd1d39bdd39b00b7dbe4afae4b557f9d"}, - {file = "pydantic-1.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0ab53b609c11dfc0c060d94335993cc2b95b2150e25583bec37a49b2d6c6c3f"}, - {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9613fadad06b4f3bc5db2653ce2f22e0de84a7c6c293909b48f6ed37b83c61f"}, - {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df7800cb1984d8f6e249351139667a8c50a379009271ee6236138a22a0c0f319"}, - {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0c6fafa0965b539d7aab0a673a046466d23b86e4b0e8019d25fd53f4df62c277"}, - {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e82d4566fcd527eae8b244fa952d99f2ca3172b7e97add0b43e2d97ee77f81ab"}, - {file = "pydantic-1.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:ab523c31e22943713d80d8d342d23b6f6ac4b792a1e54064a8d0cf78fd64e800"}, - {file = "pydantic-1.10.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:666bdf6066bf6dbc107b30d034615d2627e2121506c555f73f90b54a463d1f33"}, - {file = "pydantic-1.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:35db5301b82e8661fa9c505c800d0990bc14e9f36f98932bb1d248c0ac5cada5"}, - {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90c1e29f447557e9e26afb1c4dbf8768a10cc676e3781b6a577841ade126b85"}, - {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93e766b4a8226e0708ef243e843105bf124e21331694367f95f4e3b4a92bbb3f"}, - {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88f195f582851e8db960b4a94c3e3ad25692c1c1539e2552f3df7a9e972ef60e"}, - {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:34d327c81e68a1ecb52fe9c8d50c8a9b3e90d3c8ad991bfc8f953fb477d42fb4"}, - {file = "pydantic-1.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:d532bf00f381bd6bc62cabc7d1372096b75a33bc197a312b03f5838b4fb84edd"}, - {file = "pydantic-1.10.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d5b8641c24886d764a74ec541d2fc2c7fb19f6da2a4001e6d580ba4a38f7878"}, - {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1f6cb446470b7ddf86c2e57cd119a24959af2b01e552f60705910663af09a4"}, - {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33b60054b2136aef8cf190cd4c52a3daa20b2263917c49adad20eaf381e823b"}, - {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1952526ba40b220b912cdc43c1c32bcf4a58e3f192fa313ee665916b26befb68"}, - {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bb14388ec45a7a0dc429e87def6396f9e73c8c77818c927b6a60706603d5f2ea"}, - {file = "pydantic-1.10.8-cp37-cp37m-win_amd64.whl", hash = "sha256:16f8c3e33af1e9bb16c7a91fc7d5fa9fe27298e9f299cff6cb744d89d573d62c"}, - {file = "pydantic-1.10.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ced8375969673929809d7f36ad322934c35de4af3b5e5b09ec967c21f9f7887"}, - {file = "pydantic-1.10.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93e6bcfccbd831894a6a434b0aeb1947f9e70b7468f274154d03d71fabb1d7c6"}, - {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:191ba419b605f897ede9892f6c56fb182f40a15d309ef0142212200a10af4c18"}, - {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052d8654cb65174d6f9490cc9b9a200083a82cf5c3c5d3985db765757eb3b375"}, - {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ceb6a23bf1ba4b837d0cfe378329ad3f351b5897c8d4914ce95b85fba96da5a1"}, - {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f2e754d5566f050954727c77f094e01793bcb5725b663bf628fa6743a5a9108"}, - {file = "pydantic-1.10.8-cp38-cp38-win_amd64.whl", hash = "sha256:6a82d6cda82258efca32b40040228ecf43a548671cb174a1e81477195ed3ed56"}, - {file = "pydantic-1.10.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e59417ba8a17265e632af99cc5f35ec309de5980c440c255ab1ca3ae96a3e0e"}, - {file = "pydantic-1.10.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84d80219c3f8d4cad44575e18404099c76851bc924ce5ab1c4c8bb5e2a2227d0"}, - {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4148e635994d57d834be1182a44bdb07dd867fa3c2d1b37002000646cc5459"}, - {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12f7b0bf8553e310e530e9f3a2f5734c68699f42218bf3568ef49cd9b0e44df4"}, - {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42aa0c4b5c3025483240a25b09f3c09a189481ddda2ea3a831a9d25f444e03c1"}, - {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17aef11cc1b997f9d574b91909fed40761e13fac438d72b81f902226a69dac01"}, - {file = "pydantic-1.10.8-cp39-cp39-win_amd64.whl", hash = "sha256:66a703d1983c675a6e0fed8953b0971c44dba48a929a2000a493c3772eb61a5a"}, - {file = "pydantic-1.10.8-py3-none-any.whl", hash = "sha256:7456eb22ed9aaa24ff3e7b4757da20d9e5ce2a81018c1b3ebd81a0b88a18f3b2"}, - {file = "pydantic-1.10.8.tar.gz", hash = "sha256:1410275520dfa70effadf4c21811d755e7ef9bb1f1d077a21958153a92c8d9ca"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] - -[[package]] -name = "pyee" -version = "9.0.4" -description = "A port of node.js's EventEmitter to python." -optional = false -python-versions = "*" -files = [ - {file = "pyee-9.0.4-py2.py3-none-any.whl", hash = "sha256:9f066570130c554e9cc12de5a9d86f57c7ee47fece163bbdaa3e9c933cfbdfa5"}, - {file = "pyee-9.0.4.tar.gz", hash = "sha256:2770c4928abc721f46b705e6a72b0c59480c4a69c9a83ca0b00bb994f1ea4b32"}, -] - -[package.dependencies] -typing-extensions = "*" - -[[package]] -name = "pygments" -version = "2.15.1" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, -] - -[package.extras] -plugins = ["importlib-metadata"] - -[[package]] -name = "pyparsing" -version = "3.0.9" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, - {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-dotenv" -version = "1.0.0" -description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false -python-versions = ">=3.8" -files = [ - {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, - {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, -] - -[package.extras] -cli = ["click (>=5.0)"] - -[[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, - {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, - {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, - {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, - {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] - -[[package]] -name = "reactpy" -version = "1.0.0" -description = "Reactive user interfaces with pure Python" -optional = false -python-versions = ">=3.9" -files = [] -develop = false - -[package.dependencies] -anyio = ">=3" -asgiref = ">=3" -colorlog = ">=6" -fastapi = {version = ">=0.63.0", optional = true, markers = "extra == \"fastapi\""} -fastjsonschema = ">=2.14.5" -flask = {version = "*", optional = true, markers = "extra == \"flask\""} -flask-cors = {version = "*", optional = true, markers = "extra == \"flask\""} -flask-sock = {version = "*", optional = true, markers = "extra == \"flask\""} -jsonpatch = ">=1.32" -lxml = ">=4" -markupsafe = {version = ">=1.1.1,<2.1", optional = true, markers = "extra == \"flask\""} -mypy-extensions = ">=0.4.3" -playwright = {version = "*", optional = true, markers = "extra == \"testing\""} -requests = ">=2" -sanic = {version = ">=21", optional = true, markers = "extra == \"sanic\""} -sanic-cors = {version = "*", optional = true, markers = "extra == \"sanic\""} -starlette = {version = ">=0.13.6", optional = true, markers = "extra == \"starlette\""} -tornado = {version = "*", optional = true, markers = "extra == \"tornado\""} -typing-extensions = ">=3.10" -uvicorn = {version = ">=0.19.0", extras = ["standard"], optional = true, markers = "extra == \"fastapi\" or extra == \"sanic\" or extra == \"starlette\""} - -[package.extras] -all = ["reactpy[fastapi,flask,sanic,starlette,testing,tornado]"] -fastapi = ["fastapi (>=0.63.0)", "uvicorn[standard] (>=0.19.0)"] -flask = ["flask", "flask-cors", "flask-sock", "markupsafe (>=1.1.1,<2.1)"] -sanic = ["sanic (>=21)", "sanic-cors", "uvicorn[standard] (>=0.19.0)"] -starlette = ["starlette (>=0.13.6)", "uvicorn[standard] (>=0.19.0)"] -testing = ["playwright"] -tornado = ["tornado"] - -[package.source] -type = "directory" -url = "../src/py/reactpy" - -[[package]] -name = "requests" -version = "2.31.0" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "sanic" -version = "23.3.0" -description = "A web server and web framework that's written to go fast. Build fast. Run fast." -optional = false -python-versions = ">=3.7" -files = [ - {file = "sanic-23.3.0-py3-none-any.whl", hash = "sha256:7cafbd63da9c6c6d8aeb8cb4304addf8a274352ab812014386c63e55f474fbee"}, - {file = "sanic-23.3.0.tar.gz", hash = "sha256:b80ebc5c38c983cb45ae5ecc7a669a54c823ec1dff297fbd5f817b1e9e9e49af"}, -] - -[package.dependencies] -aiofiles = ">=0.6.0" -html5tagger = ">=1.2.1" -httptools = ">=0.0.10" -multidict = ">=5.0,<7.0" -sanic-routing = ">=22.8.0" -tracerite = ">=1.0.0" -ujson = {version = ">=1.35", markers = "sys_platform != \"win32\" and implementation_name == \"cpython\""} -uvloop = {version = ">=0.15.0", markers = "sys_platform != \"win32\" and implementation_name == \"cpython\""} -websockets = ">=10.0" - -[package.extras] -all = ["bandit", "beautifulsoup4", "black", "chardet (==3.*)", "coverage", "cryptography", "docutils", "enum-tools[sphinx]", "flake8", "isort (>=5.0.0)", "m2r2", "mistune (<2.0.0)", "mypy (>=0.901,<0.910)", "pygments", "pytest (==7.1.*)", "pytest-benchmark", "pytest-sanic", "sanic-testing (>=23.3.0)", "slotscheck (>=0.8.0,<1)", "sphinx (>=2.1.2)", "sphinx-rtd-theme (>=0.4.3)", "towncrier", "tox", "types-ujson", "uvicorn (<0.15.0)"] -dev = ["bandit", "beautifulsoup4", "black", "chardet (==3.*)", "coverage", "cryptography", "docutils", "flake8", "isort (>=5.0.0)", "mypy (>=0.901,<0.910)", "pygments", "pytest (==7.1.*)", "pytest-benchmark", "pytest-sanic", "sanic-testing (>=23.3.0)", "slotscheck (>=0.8.0,<1)", "towncrier", "tox", "types-ujson", "uvicorn (<0.15.0)"] -docs = ["docutils", "enum-tools[sphinx]", "m2r2", "mistune (<2.0.0)", "pygments", "sphinx (>=2.1.2)", "sphinx-rtd-theme (>=0.4.3)"] -ext = ["sanic-ext"] -http3 = ["aioquic"] -test = ["bandit", "beautifulsoup4", "black", "chardet (==3.*)", "coverage", "docutils", "flake8", "isort (>=5.0.0)", "mypy (>=0.901,<0.910)", "pygments", "pytest (==7.1.*)", "pytest-benchmark", "pytest-sanic", "sanic-testing (>=23.3.0)", "slotscheck (>=0.8.0,<1)", "types-ujson", "uvicorn (<0.15.0)"] - -[[package]] -name = "sanic-cors" -version = "2.2.0" -description = "A Sanic extension adding a decorator for CORS support. Based on flask-cors by Cory Dolphin." -optional = false -python-versions = "*" -files = [ - {file = "Sanic-Cors-2.2.0.tar.gz", hash = "sha256:f8d7515da4c8b837871d422c66314c4b5704396a78894b59c50e26aa72a95873"}, - {file = "Sanic_Cors-2.2.0-py2.py3-none-any.whl", hash = "sha256:c3b133ff1f0bb609a53db35f727f5c371dc4ebeb6be4cc2c37c19dd8b9301115"}, -] - -[package.dependencies] -packaging = ">=21.3" -sanic = ">=21.9.3" - -[[package]] -name = "sanic-routing" -version = "22.8.0" -description = "Core routing component for Sanic" -optional = false -python-versions = "*" -files = [ - {file = "sanic-routing-22.8.0.tar.gz", hash = "sha256:305729b4e0bf01f074044a2a315ff401fa7eeffb009eec1d2c81d35e1038ddfc"}, - {file = "sanic_routing-22.8.0-py3-none-any.whl", hash = "sha256:9a928ed9e19a36bc019223be90a5da0ab88cdd76b101e032510b6a7073c017e9"}, -] - -[[package]] -name = "simple-websocket" -version = "0.10.0" -description = "Simple WebSocket server and client for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "simple-websocket-0.10.0.tar.gz", hash = "sha256:82c0b0b1006d5490f09ff66392394d90dd758285635edad241e093e9a8abd3eb"}, - {file = "simple_websocket-0.10.0-py3-none-any.whl", hash = "sha256:fc1bc56c393a187e7268f8ab99da1a8e8da9b5dfb7769a2f3b8dada00067745b"}, -] - -[package.dependencies] -wsproto = "*" - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.0" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -optional = false -python-versions = "*" -files = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] - -[[package]] -name = "soupsieve" -version = "2.4.1" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, -] - -[[package]] -name = "sphinx" -version = "4.5.0" -description = "Python documentation generator" -optional = false -python-versions = ">=3.6" -files = [ - {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"}, - {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"}, -] - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -snowballstemmer = ">=1.1" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] - -[[package]] -name = "sphinx-autobuild" -version = "2021.3.14" -description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." -optional = false -python-versions = ">=3.6" -files = [ - {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, - {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, -] - -[package.dependencies] -colorama = "*" -livereload = "*" -sphinx = "*" - -[package.extras] -test = ["pytest", "pytest-cov"] - -[[package]] -name = "sphinx-autodoc-typehints" -version = "1.19.1" -description = "Type hints (PEP 484) support for the Sphinx autodoc extension" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx_autodoc_typehints-1.19.1-py3-none-any.whl", hash = "sha256:9be46aeeb1b315eb5df1f3a7cb262149895d16c7d7dcd77b92513c3c3a1e85e6"}, - {file = "sphinx_autodoc_typehints-1.19.1.tar.gz", hash = "sha256:6c841db55e0e9be0483ff3962a2152b60e79306f4288d8c4e7e86ac84486a5ea"}, -] - -[package.dependencies] -Sphinx = ">=4.5" - -[package.extras] -testing = ["covdefaults (>=2.2)", "coverage (>=6.3)", "diff-cover (>=6.4)", "nptyping (>=2.1.2)", "pytest (>=7.1)", "pytest-cov (>=3)", "sphobjinv (>=2)", "typing-extensions (>=4.1)"] -type-comments = ["typed-ast (>=1.5.2)"] - -[[package]] -name = "sphinx-copybutton" -version = "0.5.2" -description = "Add a copy button to each of your code cells." -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd"}, - {file = "sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e"}, -] - -[package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code-style = ["pre-commit (==2.12.1)"] -rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] - -[[package]] -name = "sphinx-design" -version = "0.4.1" -description = "A sphinx extension for designing beautiful, view size responsive web components." -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx_design-0.4.1-py3-none-any.whl", hash = "sha256:23bf5705eb31296d4451f68b0222a698a8a84396ffe8378dfd9319ba7ab8efd9"}, - {file = "sphinx_design-0.4.1.tar.gz", hash = "sha256:5b6418ba4a2dc3d83592ea0ff61a52a891fe72195a4c3a18b2fa1c7668ce4708"}, -] - -[package.dependencies] -sphinx = ">=4,<7" - -[package.extras] -code-style = ["pre-commit (>=2.12,<3.0)"] -rtd = ["myst-parser (>=0.18.0,<2)"] -testing = ["myst-parser (>=0.18.0,<2)", "pytest (>=7.1,<8.0)", "pytest-cov", "pytest-regressions"] -theme-furo = ["furo (>=2022.06.04,<2022.07)"] -theme-pydata = ["pydata-sphinx-theme (>=0.9.0,<0.10.0)"] -theme-rtd = ["sphinx-rtd-theme (>=1.0,<2.0)"] -theme-sbt = ["sphinx-book-theme (>=0.3.0,<0.4.0)"] - -[[package]] -name = "sphinx-reredirects" -version = "0.1.2" -description = "Handles redirects for moved pages in Sphinx documentation projects" -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinx_reredirects-0.1.2-py3-none-any.whl", hash = "sha256:3a22161771aadd448bb608a4fe7277252182a337af53c18372b7104531d71489"}, - {file = "sphinx_reredirects-0.1.2.tar.gz", hash = "sha256:a0e7213304759b01edc22f032f1715a1c61176fc8f167164e7a52b9feec9ac64"}, -] - -[package.dependencies] -sphinx = "*" - -[[package]] -name = "sphinx-resolve-py-references" -version = "0.1.0" -description = "Better python object resolution in Sphinx" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinx_resolve_py_references-0.1.0-py2.py3-none-any.whl", hash = "sha256:ccf44a6b62d75c3a568285f4e1815734088c1a7cab7bbb7935bb22fbf0d78bc2"}, - {file = "sphinx_resolve_py_references-0.1.0.tar.gz", hash = "sha256:0f87c06b29ec128964aee2e40d170d1d3c0e5f4955b2618a89ca724f42385372"}, -] - -[package.dependencies] -sphinx = "*" - -[[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.4" -description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -optional = false -python-versions = ">=3.8" -files = [ - {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, - {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.1" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, - {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["html5lib", "pytest"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] - -[package.extras] -test = ["flake8", "mypy", "pytest"] - -[[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -optional = false -python-versions = ">=3.5" -files = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, -] - -[package.extras] -lint = ["docutils-stubs", "flake8", "mypy"] -test = ["pytest"] - -[[package]] -name = "sphinxext-opengraph" -version = "0.8.2" -description = "Sphinx Extension to enable OGP support" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sphinxext-opengraph-0.8.2.tar.gz", hash = "sha256:45a693b6704052c426576f0a1f630649c55b4188bc49eb63e9587e24a923db39"}, - {file = "sphinxext_opengraph-0.8.2-py3-none-any.whl", hash = "sha256:6a05bdfe5176d9dd0a1d58a504f17118362ab976631213cd36fb44c4c40544c9"}, -] - -[package.dependencies] -matplotlib = "*" -sphinx = ">=4.0" - -[[package]] -name = "starlette" -version = "0.27.0" -description = "The little ASGI library that shines." -optional = false -python-versions = ">=3.7" -files = [ - {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"}, - {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"}, -] - -[package.dependencies] -anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] - -[[package]] -name = "tornado" -version = "6.3.2" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = false -python-versions = ">= 3.8" -files = [ - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, - {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, - {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, - {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, -] - -[[package]] -name = "tracerite" -version = "1.1.0" -description = "Human-readable HTML tracebacks for Python exceptions" -optional = false -python-versions = "*" -files = [ - {file = "tracerite-1.1.0-py3-none-any.whl", hash = "sha256:4cccac04db05eeeabda45e72b57199e147fa2f73cf64d89cfd625df321bd2ab6"}, - {file = "tracerite-1.1.0.tar.gz", hash = "sha256:041dab8fd4bb405f73506293ac7438a2d311e5f9044378ba7d9a6540392f9e4b"}, -] - -[package.dependencies] -html5tagger = ">=1.2.1" - -[[package]] -name = "typing-extensions" -version = "4.6.3" -description = "Backported and Experimental Type Hints for Python 3.7+" -optional = false -python-versions = ">=3.7" -files = [ - {file = "typing_extensions-4.6.3-py3-none-any.whl", hash = "sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26"}, - {file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"}, -] - -[[package]] -name = "ujson" -version = "5.7.0" -description = "Ultra fast JSON encoder and decoder for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ujson-5.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5eba5e69e4361ac3a311cf44fa71bc619361b6e0626768a494771aacd1c2f09b"}, - {file = "ujson-5.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aae4d9e1b4c7b61780f0a006c897a4a1904f862fdab1abb3ea8f45bd11aa58f3"}, - {file = "ujson-5.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2e43ccdba1cb5c6d3448eadf6fc0dae7be6c77e357a3abc968d1b44e265866d"}, - {file = "ujson-5.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54384ce4920a6d35fa9ea8e580bc6d359e3eb961fa7e43f46c78e3ed162d56ff"}, - {file = "ujson-5.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24ad1aa7fc4e4caa41d3d343512ce68e41411fb92adf7f434a4d4b3749dc8f58"}, - {file = "ujson-5.7.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:afff311e9f065a8f03c3753db7011bae7beb73a66189c7ea5fcb0456b7041ea4"}, - {file = "ujson-5.7.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e80f0d03e7e8646fc3d79ed2d875cebd4c83846e129737fdc4c2532dbd43d9e"}, - {file = "ujson-5.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:137831d8a0db302fb6828ee21c67ad63ac537bddc4376e1aab1c8573756ee21c"}, - {file = "ujson-5.7.0-cp310-cp310-win32.whl", hash = "sha256:7df3fd35ebc14dafeea031038a99232b32f53fa4c3ecddb8bed132a43eefb8ad"}, - {file = "ujson-5.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:af4639f684f425177d09ae409c07602c4096a6287027469157bfb6f83e01448b"}, - {file = "ujson-5.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b0f2680ce8a70f77f5d70aaf3f013d53e6af6d7058727a35d8ceb4a71cdd4e9"}, - {file = "ujson-5.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a19fd8e7d8cc58a169bea99fed5666023adf707a536d8f7b0a3c51dd498abf"}, - {file = "ujson-5.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6abb8e6d8f1ae72f0ed18287245f5b6d40094e2656d1eab6d99d666361514074"}, - {file = "ujson-5.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8cd622c069368d5074bd93817b31bdb02f8d818e57c29e206f10a1f9c6337dd"}, - {file = "ujson-5.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14f9082669f90e18e64792b3fd0bf19f2b15e7fe467534a35ea4b53f3bf4b755"}, - {file = "ujson-5.7.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d7ff6ebb43bc81b057724e89550b13c9a30eda0f29c2f506f8b009895438f5a6"}, - {file = "ujson-5.7.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f7f241488879d91a136b299e0c4ce091996c684a53775e63bb442d1a8e9ae22a"}, - {file = "ujson-5.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5593263a7fcfb934107444bcfba9dde8145b282de0ee9f61e285e59a916dda0f"}, - {file = "ujson-5.7.0-cp311-cp311-win32.whl", hash = "sha256:26c2b32b489c393106e9cb68d0a02e1a7b9d05a07429d875c46b94ee8405bdb7"}, - {file = "ujson-5.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:ed24406454bb5a31df18f0a423ae14beb27b28cdfa34f6268e7ebddf23da807e"}, - {file = "ujson-5.7.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18679484e3bf9926342b1c43a3bd640f93a9eeeba19ef3d21993af7b0c44785d"}, - {file = "ujson-5.7.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee295761e1c6c30400641f0a20d381633d7622633cdf83a194f3c876a0e4b7e"}, - {file = "ujson-5.7.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b738282e12a05f400b291966630a98d622da0938caa4bc93cf65adb5f4281c60"}, - {file = "ujson-5.7.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00343501dbaa5172e78ef0e37f9ebd08040110e11c12420ff7c1f9f0332d939e"}, - {file = "ujson-5.7.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c0d1f7c3908357ee100aa64c4d1cf91edf99c40ac0069422a4fd5fd23b263263"}, - {file = "ujson-5.7.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a5d2f44331cf04689eafac7a6596c71d6657967c07ac700b0ae1c921178645da"}, - {file = "ujson-5.7.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:16b2254a77b310f118717715259a196662baa6b1f63b1a642d12ab1ff998c3d7"}, - {file = "ujson-5.7.0-cp37-cp37m-win32.whl", hash = "sha256:6faf46fa100b2b89e4db47206cf8a1ffb41542cdd34dde615b2fc2288954f194"}, - {file = "ujson-5.7.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ff0004c3f5a9a6574689a553d1b7819d1a496b4f005a7451f339dc2d9f4cf98c"}, - {file = "ujson-5.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:75204a1dd7ec6158c8db85a2f14a68d2143503f4bafb9a00b63fe09d35762a5e"}, - {file = "ujson-5.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7312731c7826e6c99cdd3ac503cd9acd300598e7a80bcf41f604fee5f49f566c"}, - {file = "ujson-5.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b9dc5a90e2149643df7f23634fe202fed5ebc787a2a1be95cf23632b4d90651"}, - {file = "ujson-5.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6a6961fc48821d84b1198a09516e396d56551e910d489692126e90bf4887d29"}, - {file = "ujson-5.7.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b01a9af52a0d5c46b2c68e3f258fdef2eacaa0ce6ae3e9eb97983f5b1166edb6"}, - {file = "ujson-5.7.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7316d3edeba8a403686cdcad4af737b8415493101e7462a70ff73dd0609eafc"}, - {file = "ujson-5.7.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ee997799a23227e2319a3f8817ce0b058923dbd31904761b788dc8f53bd3e30"}, - {file = "ujson-5.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dda9aa4c33435147262cd2ea87c6b7a1ca83ba9b3933ff7df34e69fee9fced0c"}, - {file = "ujson-5.7.0-cp38-cp38-win32.whl", hash = "sha256:bea8d30e362180aafecabbdcbe0e1f0b32c9fa9e39c38e4af037b9d3ca36f50c"}, - {file = "ujson-5.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:c96e3b872bf883090ddf32cc41957edf819c5336ab0007d0cf3854e61841726d"}, - {file = "ujson-5.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6411aea4c94a8e93c2baac096fbf697af35ba2b2ed410b8b360b3c0957a952d3"}, - {file = "ujson-5.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d3b3499c55911f70d4e074c626acdb79a56f54262c3c83325ffb210fb03e44d"}, - {file = "ujson-5.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:341f891d45dd3814d31764626c55d7ab3fd21af61fbc99d070e9c10c1190680b"}, - {file = "ujson-5.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f242eec917bafdc3f73a1021617db85f9958df80f267db69c76d766058f7b19"}, - {file = "ujson-5.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c3af9f9f22a67a8c9466a32115d9073c72a33ae627b11de6f592df0ee09b98b6"}, - {file = "ujson-5.7.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a3d794afbf134df3056a813e5c8a935208cddeae975bd4bc0ef7e89c52f0ce0"}, - {file = "ujson-5.7.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:800bf998e78dae655008dd10b22ca8dc93bdcfcc82f620d754a411592da4bbf2"}, - {file = "ujson-5.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b5ac3d5c5825e30b438ea92845380e812a476d6c2a1872b76026f2e9d8060fc2"}, - {file = "ujson-5.7.0-cp39-cp39-win32.whl", hash = "sha256:cd90027e6d93e8982f7d0d23acf88c896d18deff1903dd96140613389b25c0dd"}, - {file = "ujson-5.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:523ee146cdb2122bbd827f4dcc2a8e66607b3f665186bce9e4f78c9710b6d8ab"}, - {file = "ujson-5.7.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e87cec407ec004cf1b04c0ed7219a68c12860123dfb8902ef880d3d87a71c172"}, - {file = "ujson-5.7.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bab10165db6a7994e67001733f7f2caf3400b3e11538409d8756bc9b1c64f7e8"}, - {file = "ujson-5.7.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b522be14a28e6ac1cf818599aeff1004a28b42df4ed4d7bc819887b9dac915fc"}, - {file = "ujson-5.7.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7592f40175c723c032cdbe9fe5165b3b5903604f774ab0849363386e99e1f253"}, - {file = "ujson-5.7.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ed22f9665327a981f288a4f758a432824dc0314e4195a0eaeb0da56a477da94d"}, - {file = "ujson-5.7.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:adf445a49d9a97a5a4c9bb1d652a1528de09dd1c48b29f79f3d66cea9f826bf6"}, - {file = "ujson-5.7.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64772a53f3c4b6122ed930ae145184ebaed38534c60f3d859d8c3f00911eb122"}, - {file = "ujson-5.7.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35209cb2c13fcb9d76d249286105b4897b75a5e7f0efb0c0f4b90f222ce48910"}, - {file = "ujson-5.7.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90712dfc775b2c7a07d4d8e059dd58636bd6ff1776d79857776152e693bddea6"}, - {file = "ujson-5.7.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0e4e8981c6e7e9e637e637ad8ffe948a09e5434bc5f52ecbb82b4b4cfc092bfb"}, - {file = "ujson-5.7.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:581c945b811a3d67c27566539bfcb9705ea09cb27c4be0002f7a553c8886b817"}, - {file = "ujson-5.7.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d36a807a24c7d44f71686685ae6fbc8793d784bca1adf4c89f5f780b835b6243"}, - {file = "ujson-5.7.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b4257307e3662aa65e2644a277ca68783c5d51190ed9c49efebdd3cbfd5fa44"}, - {file = "ujson-5.7.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea7423d8a2f9e160c5e011119741682414c5b8dce4ae56590a966316a07a4618"}, - {file = "ujson-5.7.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c592eb91a5968058a561d358d0fef59099ed152cfb3e1cd14eee51a7a93879e"}, - {file = "ujson-5.7.0.tar.gz", hash = "sha256:e788e5d5dcae8f6118ac9b45d0b891a0d55f7ac480eddcb7f07263f2bcf37b23"}, -] - -[[package]] -name = "urllib3" -version = "2.0.2" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.7" -files = [ - {file = "urllib3-2.0.2-py3-none-any.whl", hash = "sha256:d055c2f9d38dc53c808f6fdc8eab7360b6fdbbde02340ed25cfbcd817c62469e"}, - {file = "urllib3-2.0.2.tar.gz", hash = "sha256:61717a1095d7e155cdb737ac7bb2f4324a858a1e2e6466f6d03ff630ca68d3cc"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "uvicorn" -version = "0.22.0" -description = "The lightning-fast ASGI server." -optional = false -python-versions = ">=3.7" -files = [ - {file = "uvicorn-0.22.0-py3-none-any.whl", hash = "sha256:e9434d3bbf05f310e762147f769c9f21235ee118ba2d2bf1155a7196448bd996"}, - {file = "uvicorn-0.22.0.tar.gz", hash = "sha256:79277ae03db57ce7d9aa0567830bbb51d7a612f54d6e1e3e92da3ef24c2c8ed8"}, -] - -[package.dependencies] -click = ">=7.0" -colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} -h11 = ">=0.8" -httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} -python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} -pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} -uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} -watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} -websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "uvloop" -version = "0.17.0" -description = "Fast implementation of asyncio event loop on top of libuv" -optional = false -python-versions = ">=3.7" -files = [ - {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718"}, - {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c"}, - {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d"}, - {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024"}, - {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa"}, - {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811"}, - {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c"}, - {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e"}, - {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539"}, - {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4"}, - {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05"}, - {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376"}, - {file = "uvloop-0.17.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b"}, - {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8"}, - {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62"}, - {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d"}, - {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667"}, - {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738"}, - {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20"}, - {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f"}, - {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595"}, - {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578"}, - {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474"}, - {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b"}, - {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c"}, - {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8"}, - {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c"}, - {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9"}, - {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded"}, - {file = "uvloop-0.17.0.tar.gz", hash = "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1"}, -] - -[package.extras] -dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)", "pytest (>=3.6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] - -[[package]] -name = "watchfiles" -version = "0.19.0" -description = "Simple, modern and high performance file watching and code reload in python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"}, - {file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"}, - {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"}, - {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"}, - {file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"}, - {file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"}, - {file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"}, - {file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"}, -] - -[package.dependencies] -anyio = ">=3.0.0" - -[[package]] -name = "websockets" -version = "11.0.3" -description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"}, - {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"}, - {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"}, - {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"}, - {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"}, - {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"}, - {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"}, - {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"}, - {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"}, - {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"}, - {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"}, - {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"}, - {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"}, - {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"}, - {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"}, - {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"}, - {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"}, - {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"}, - {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"}, - {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"}, - {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"}, - {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"}, - {file = "websockets-11.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152"}, - {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f"}, - {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b"}, - {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb"}, - {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007"}, - {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0"}, - {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af"}, - {file = "websockets-11.0.3-cp37-cp37m-win32.whl", hash = "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f"}, - {file = "websockets-11.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de"}, - {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0"}, - {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae"}, - {file = "websockets-11.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99"}, - {file = "websockets-11.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa"}, - {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86"}, - {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c"}, - {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0"}, - {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e"}, - {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788"}, - {file = "websockets-11.0.3-cp38-cp38-win32.whl", hash = "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74"}, - {file = "websockets-11.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f"}, - {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"}, - {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"}, - {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"}, - {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"}, - {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"}, - {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"}, - {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"}, - {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"}, - {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"}, - {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"}, - {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"}, - {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"}, - {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"}, - {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"}, - {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"}, - {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, -] - -[[package]] -name = "werkzeug" -version = "2.1.2" -description = "The comprehensive WSGI web application library." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, - {file = "Werkzeug-2.1.2.tar.gz", hash = "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6"}, -] - -[package.extras] -watchdog = ["watchdog"] - -[[package]] -name = "wsproto" -version = "1.2.0" -description = "WebSockets state-machine based protocol implementation" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"}, - {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"}, -] - -[package.dependencies] -h11 = ">=0.9.0,<1" - -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - -[metadata] -lock-version = "2.0" -python-versions = "^3.9" -content-hash = "629118cfac10f1dab4c39c6ccd50bd69ca68a7fc05dd2baf1d020082d6b19e4e" diff --git a/docs/pyproject.toml b/docs/pyproject.toml deleted file mode 100644 index d2f47c577..000000000 --- a/docs/pyproject.toml +++ /dev/null @@ -1,23 +0,0 @@ -[tool.poetry] -name = "docs" -version = "0.0.0" -description = "docs" -authors = ["rmorshea "] -readme = "README.md" - -[tool.poetry.dependencies] -python = "^3.9" -reactpy = { path = "../src/py/reactpy", extras = ["starlette", "sanic", "fastapi", "flask", "tornado", "testing"], develop = false } -furo = "2022.04.07" -sphinx = "*" -sphinx-autodoc-typehints = "*" -sphinx-copybutton = "*" -sphinx-autobuild = "*" -sphinx-reredirects = "*" -sphinx-design = "*" -sphinx-resolve-py-references = "*" -sphinxext-opengraph = "*" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..0e7af6eb3 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,10 @@ +mkdocs +mkdocs-git-revision-date-localized-plugin +mkdocs-material +mkdocs-include-markdown-plugin +linkcheckmd +mkdocs-spellcheck[all] +mkdocs-git-authors-plugin +mkdocs-minify-plugin +mkdocs-section-index +mike diff --git a/docs/source/_custom_js/README.md b/docs/source/_custom_js/README.md deleted file mode 100644 index 4d5d75dc2..000000000 --- a/docs/source/_custom_js/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Custom Javascript for ReactPy's Docs - -Build the javascript with - -``` -npm run build -``` - -This will drop a javascript bundle into `../_static/custom.js` diff --git a/docs/source/_custom_js/package-lock.json b/docs/source/_custom_js/package-lock.json deleted file mode 100644 index 98cbb7014..000000000 --- a/docs/source/_custom_js/package-lock.json +++ /dev/null @@ -1,766 +0,0 @@ -{ - "name": "reactpy-docs-example-loader", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "reactpy-docs-example-loader", - "version": "1.0.0", - "dependencies": { - "@reactpy/client": "file:../../../src/js/packages/@reactpy/client" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^21.0.1", - "@rollup/plugin-node-resolve": "^13.1.1", - "@rollup/plugin-replace": "^3.0.0", - "prettier": "^2.2.1", - "rollup": "^2.35.1" - } - }, - "../../../src/client/packages/@reactpy/client": { - "version": "0.3.1", - "integrity": "sha512-pIK5eNwFSHKXg7ClpASWFVKyZDYxz59MSFpVaX/OqJFkrJaAxBuhKGXNTMXmuyWOL5Iyvb/ErwwDRxQRzMNkfQ==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "event-to-object": "^0.1.2", - "json-pointer": "^0.6.2" - }, - "devDependencies": { - "@types/json-pointer": "^1.0.31", - "@types/react": "^17.0", - "@types/react-dom": "^17.0", - "typescript": "^4.9.5" - }, - "peerDependencies": { - "react": ">=16 <18", - "react-dom": ">=16 <18" - } - }, - "../../../src/client/packages/client": { - "name": "@reactpy/client", - "version": "0.2.0", - "extraneous": true, - "license": "MIT", - "dependencies": { - "event-to-object": "^0.1.0", - "json-pointer": "^0.6.2" - }, - "devDependencies": { - "@types/json-pointer": "^1.0.31", - "@types/react": "^17.0", - "@types/react-dom": "^17.0", - "prettier": "^3.0.0-alpha.6", - "typescript": "^4.9.5" - }, - "peerDependencies": { - "react": ">=16 <18", - "react-dom": ">=16 <18" - } - }, - "../../../src/js/packages/@reactpy/client": { - "version": "0.3.1", - "license": "MIT", - "dependencies": { - "event-to-object": "^0.1.2", - "json-pointer": "^0.6.2" - }, - "devDependencies": { - "@types/json-pointer": "^1.0.31", - "@types/react": "^17.0", - "@types/react-dom": "^17.0", - "typescript": "^4.9.5" - }, - "peerDependencies": { - "react": ">=16 <18", - "react-dom": ">=16 <18" - } - }, - "node_modules/@reactpy/client": { - "resolved": "../../../src/js/packages/@reactpy/client", - "link": true - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", - "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^2.38.3" - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.1.tgz", - "integrity": "sha512-6QKtRevXLrmEig9UiMYt2fSvee9TyltGRfw+qSs6xjUnxwjOzTOqy+/Lpxsgjb8mJn1EQNbCDAvt89O4uzL5kw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^2.42.0" - } - }, - "node_modules/@rollup/plugin-node-resolve/node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-3.0.0.tgz", - "integrity": "sha512-3c7JCbMuYXM4PbPWT4+m/4Y6U60SgsnDT/cCyAyUKwFHg7pTSfsSQzIpETha3a3ig6OdOKzZz87D9ZXIK3qsDg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", - "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==", - "dev": true - }, - "node_modules/@types/node": { - "version": "15.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", - "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.4" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rollup": { - "version": "2.52.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.1.tgz", - "integrity": "sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - } - }, - "dependencies": { - "@reactpy/client": { - "version": "file:../../../src/js/packages/@reactpy/client", - "requires": { - "@types/json-pointer": "^1.0.31", - "@types/react": "^17.0", - "@types/react-dom": "^17.0", - "event-to-object": "^0.1.2", - "json-pointer": "^0.6.2", - "typescript": "^4.9.5" - } - }, - "@rollup/plugin-commonjs": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.1.tgz", - "integrity": "sha512-EA+g22lbNJ8p5kuZJUYyhhDK7WgJckW5g4pNN7n4mAFUM96VuwUnNT3xr2Db2iCZPI1pJPbGyfT5mS9T1dHfMg==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "commondir": "^1.0.1", - "estree-walker": "^2.0.1", - "glob": "^7.1.6", - "is-reference": "^1.2.1", - "magic-string": "^0.25.7", - "resolve": "^1.17.0" - }, - "dependencies": { - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - } - } - }, - "@rollup/plugin-node-resolve": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.1.tgz", - "integrity": "sha512-6QKtRevXLrmEig9UiMYt2fSvee9TyltGRfw+qSs6xjUnxwjOzTOqy+/Lpxsgjb8mJn1EQNbCDAvt89O4uzL5kw==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "dependencies": { - "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "requires": { - "@types/node": "*" - } - } - } - }, - "@rollup/plugin-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-3.0.0.tgz", - "integrity": "sha512-3c7JCbMuYXM4PbPWT4+m/4Y6U60SgsnDT/cCyAyUKwFHg7pTSfsSQzIpETha3a3ig6OdOKzZz87D9ZXIK3qsDg==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - } - }, - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - } - } - }, - "@types/estree": { - "version": "0.0.48", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz", - "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==", - "dev": true - }, - "@types/node": { - "version": "15.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz", - "integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "prettier": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", - "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "rollup": { - "version": "2.52.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.1.tgz", - "integrity": "sha512-/SPqz8UGnp4P1hq6wc9gdTqA2bXQXGx13TtoL03GBm6qGRI6Hm3p4Io7GeiHNLl0BsQAne1JNYY+q/apcY933w==", - "dev": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - } - } -} diff --git a/docs/source/_custom_js/package.json b/docs/source/_custom_js/package.json deleted file mode 100644 index 78d72b961..000000000 --- a/docs/source/_custom_js/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "reactpy-docs-example-loader", - "version": "1.0.0", - "description": "simple javascript client for ReactPy's documentation", - "main": "index.js", - "scripts": { - "build": "rollup --config", - "format": "prettier --ignore-path .gitignore --write ." - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^21.0.1", - "@rollup/plugin-node-resolve": "^13.1.1", - "@rollup/plugin-replace": "^3.0.0", - "prettier": "^2.2.1", - "rollup": "^2.35.1" - }, - "dependencies": { - "@reactpy/client": "file:../../../src/js/packages/@reactpy/client" - } -} diff --git a/docs/source/_custom_js/rollup.config.js b/docs/source/_custom_js/rollup.config.js deleted file mode 100644 index 48dd535cf..000000000 --- a/docs/source/_custom_js/rollup.config.js +++ /dev/null @@ -1,26 +0,0 @@ -import resolve from "@rollup/plugin-node-resolve"; -import commonjs from "@rollup/plugin-commonjs"; -import replace from "@rollup/plugin-replace"; - -export default { - input: "src/index.js", - output: { - file: "../_static/custom.js", - format: "esm", - }, - plugins: [ - resolve(), - commonjs(), - replace({ - "process.env.NODE_ENV": JSON.stringify("production"), - preventAssignment: true, - }), - ], - onwarn: function (warning) { - if (warning.code === "THIS_IS_UNDEFINED") { - // skip warning where `this` is undefined at the top level of a module - return; - } - console.warn(warning.message); - }, -}; diff --git a/docs/source/_custom_js/src/index.js b/docs/source/_custom_js/src/index.js deleted file mode 100644 index 505adedd0..000000000 --- a/docs/source/_custom_js/src/index.js +++ /dev/null @@ -1,94 +0,0 @@ -import { SimpleReactPyClient, mount } from "@reactpy/client"; - -let didMountDebug = false; - -export function mountWidgetExample( - mountID, - viewID, - reactpyServerHost, - useActivateButton, -) { - let reactpyHost, reactpyPort; - if (reactpyServerHost) { - [reactpyHost, reactpyPort] = reactpyServerHost.split(":", 2); - } else { - reactpyHost = window.location.hostname; - reactpyPort = window.location.port; - } - - const client = new SimpleReactPyClient({ - serverLocation: { - url: `${window.location.protocol}//${reactpyHost}:${reactpyPort}`, - route: "/", - query: `?view_id=${viewID}`, - }, - }); - - const mountEl = document.getElementById(mountID); - let isMounted = false; - triggerIfInViewport(mountEl, () => { - if (!isMounted) { - activateView(mountEl, client, useActivateButton); - isMounted = true; - } - }); -} - -function activateView(mountEl, client, useActivateButton) { - if (!useActivateButton) { - mount(mountEl, client); - return; - } - - const enableWidgetButton = document.createElement("button"); - enableWidgetButton.appendChild(document.createTextNode("Activate")); - enableWidgetButton.setAttribute("class", "enable-widget-button"); - - enableWidgetButton.addEventListener("click", () => - fadeOutElementThenCallback(enableWidgetButton, () => { - { - mountEl.removeChild(enableWidgetButton); - mountEl.setAttribute("class", "interactive widget-container"); - mountWithLayoutServer(mountEl, serverInfo); - } - }), - ); - - function fadeOutElementThenCallback(element, callback) { - { - var op = 1; // initial opacity - var timer = setInterval(function () { - { - if (op < 0.001) { - { - clearInterval(timer); - element.style.display = "none"; - callback(); - } - } - element.style.opacity = op; - element.style.filter = "alpha(opacity=" + op * 100 + ")"; - op -= op * 0.5; - } - }, 50); - } - } - - mountEl.appendChild(enableWidgetButton); -} - -function triggerIfInViewport(element, callback) { - const observer = new window.IntersectionObserver( - ([entry]) => { - if (entry.isIntersecting) { - callback(); - } - }, - { - root: null, - threshold: 0.1, // set offset 0.1 means trigger if at least 10% of element in viewport - }, - ); - - observer.observe(element); -} diff --git a/docs/source/_exts/async_doctest.py b/docs/source/_exts/async_doctest.py deleted file mode 100644 index 96024d488..000000000 --- a/docs/source/_exts/async_doctest.py +++ /dev/null @@ -1,47 +0,0 @@ -from doctest import DocTest, DocTestRunner -from textwrap import indent -from typing import Any - -from sphinx.application import Sphinx -from sphinx.ext.doctest import DocTestBuilder -from sphinx.ext.doctest import setup as doctest_setup - -test_template = """ -import asyncio as __test_template_asyncio - -async def __test_template__main(): - - {test} - - globals().update(locals()) - -__test_template_asyncio.run(__test_template__main()) -""" - - -class TestRunnerWrapper: - def __init__(self, runner: DocTestRunner): - self._runner = runner - - def __getattr__(self, name: str) -> Any: - return getattr(self._runner, name) - - def run(self, test: DocTest, *args: Any, **kwargs: Any) -> Any: - for ex in test.examples: - ex.source = test_template.format(test=indent(ex.source, " ").strip()) - return self._runner.run(test, *args, **kwargs) - - -class AsyncDoctestBuilder(DocTestBuilder): - @property - def test_runner(self) -> DocTestRunner: - return self._test_runner - - @test_runner.setter - def test_runner(self, value: DocTestRunner) -> None: - self._test_runner = TestRunnerWrapper(value) - - -def setup(app: Sphinx) -> None: - doctest_setup(app) - app.add_builder(AsyncDoctestBuilder, override=True) diff --git a/docs/source/_exts/autogen_api_docs.py b/docs/source/_exts/autogen_api_docs.py deleted file mode 100644 index b95d85a99..000000000 --- a/docs/source/_exts/autogen_api_docs.py +++ /dev/null @@ -1,146 +0,0 @@ -from __future__ import annotations - -import sys -from collections.abc import Collection, Iterator -from pathlib import Path - -from sphinx.application import Sphinx - -HERE = Path(__file__).parent -SRC = HERE.parent.parent.parent / "src" -PYTHON_PACKAGE = SRC / "py" / "reactpy" / "reactpy" - -AUTO_DIR = HERE.parent / "_auto" -AUTO_DIR.mkdir(exist_ok=True) - -API_FILE = AUTO_DIR / "apis.rst" - -# All valid RST section symbols - it shouldn't be realistically possible to exhaust them -SECTION_SYMBOLS = r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" - -AUTODOC_TEMPLATE_WITH_MEMBERS = """\ -.. automodule:: {module} - :members: - :ignore-module-all: -""" - -AUTODOC_TEMPLATE_WITHOUT_MEMBERS = """\ -.. automodule:: {module} - :ignore-module-all: -""" - -TITLE = """\ -========== -Python API -========== -""" - - -def generate_api_docs(): - content = [TITLE] - - for file in walk_python_files(PYTHON_PACKAGE, ignore_dirs={"__pycache__"}): - if file.name == "__init__.py": - if file.parent != PYTHON_PACKAGE: - content.append(make_package_section(file)) - else: - content.append(make_module_section(file)) - - API_FILE.write_text("\n".join(content)) - - -def make_package_section(file: Path) -> str: - parent_dir = file.parent - symbol = get_section_symbol(parent_dir) - section_name = f"``{parent_dir.name}``" - module_name = get_module_name(parent_dir) - return ( - section_name - + "\n" - + (symbol * len(section_name)) - + "\n" - + AUTODOC_TEMPLATE_WITHOUT_MEMBERS.format(module=module_name) - ) - - -def make_module_section(file: Path) -> str: - symbol = get_section_symbol(file) - section_name = f"``{file.stem}``" - module_name = get_module_name(file) - return ( - section_name - + "\n" - + (symbol * len(section_name)) - + "\n" - + AUTODOC_TEMPLATE_WITH_MEMBERS.format(module=module_name) - ) - - -def get_module_name(path: Path) -> str: - return ".".join(path.with_suffix("").relative_to(PYTHON_PACKAGE.parent).parts) - - -def get_section_symbol(path: Path) -> str: - rel_path = path.relative_to(PYTHON_PACKAGE) - rel_path_parts = rel_path.parts - if len(rel_path_parts) > len(SECTION_SYMBOLS): - msg = f"package structure is too deep - ran out of section symbols: {rel_path}" - raise RuntimeError(msg) - return SECTION_SYMBOLS[len(rel_path_parts) - 1] - - -def walk_python_files(root: Path, ignore_dirs: Collection[str]) -> Iterator[Path]: - """Iterate over Python files - - We yield in a particular order to get the correction title section structure. Given - a directory structure of the form:: - - project/ - __init__.py - /package - __init__.py - module_a.py - module_b.py - - We yield the files in this order:: - - project/__init__.py - project/package/__init__.py - project/package/module_a.py - project/module_b.py - - In this way we generate the section titles in the appropriate order:: - - project - ======= - - project.package - --------------- - - project.package.module_a - ------------------------ - - """ - for path in sorted( - root.iterdir(), - key=lambda path: ( - # __init__.py files first - int(not path.name == "__init__.py"), - # then directories - int(not path.is_dir()), - # sort by file name last - path.name, - ), - ): - if path.is_dir(): - if (path / "__init__.py").exists() and path.name not in ignore_dirs: - yield from walk_python_files(path, ignore_dirs) - elif path.suffix == ".py": - yield path - - -def setup(app: Sphinx) -> None: - if sys.platform == "win32" and sys.version_info[:2] == (3, 7): - return None - generate_api_docs() - return None diff --git a/docs/source/_exts/build_custom_js.py b/docs/source/_exts/build_custom_js.py deleted file mode 100644 index 97857ba74..000000000 --- a/docs/source/_exts/build_custom_js.py +++ /dev/null @@ -1,12 +0,0 @@ -import subprocess -from pathlib import Path - -from sphinx.application import Sphinx - -SOURCE_DIR = Path(__file__).parent.parent -CUSTOM_JS_DIR = SOURCE_DIR / "_custom_js" - - -def setup(app: Sphinx) -> None: - subprocess.run("npm install", cwd=CUSTOM_JS_DIR, shell=True) # noqa S607 - subprocess.run("npm run build", cwd=CUSTOM_JS_DIR, shell=True) # noqa S607 diff --git a/docs/source/_exts/copy_vdom_json_schema.py b/docs/source/_exts/copy_vdom_json_schema.py deleted file mode 100644 index 38fc171ac..000000000 --- a/docs/source/_exts/copy_vdom_json_schema.py +++ /dev/null @@ -1,17 +0,0 @@ -import json -from pathlib import Path - -from sphinx.application import Sphinx - -from reactpy.core.vdom import VDOM_JSON_SCHEMA - - -def setup(app: Sphinx) -> None: - schema_file = Path(__file__).parent.parent / "vdom-json-schema.json" - current_schema = json.dumps(VDOM_JSON_SCHEMA, indent=2, sort_keys=True) - - # We need to make this check because the autoreload system for the docs checks - # to see if the file has changed to determine whether to re-build. Thus we should - # only write to the file if its contents will be different. - if not schema_file.exists() or schema_file.read_text() != current_schema: - schema_file.write_text(current_schema) diff --git a/docs/source/_exts/custom_autosectionlabel.py b/docs/source/_exts/custom_autosectionlabel.py deleted file mode 100644 index 92ff5e2df..000000000 --- a/docs/source/_exts/custom_autosectionlabel.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Mostly copied from sphinx.ext.autosectionlabel - -See Sphinx BSD license: -https://github.com/sphinx-doc/sphinx/blob/f9968594206e538f13fa1c27c065027f10d4ea27/LICENSE -""" - -from __future__ import annotations - -from fnmatch import fnmatch -from typing import Any, cast - -from docutils import nodes -from docutils.nodes import Node -from sphinx.application import Sphinx -from sphinx.domains.std import StandardDomain -from sphinx.locale import __ -from sphinx.util import logging -from sphinx.util.nodes import clean_astext - -logger = logging.getLogger(__name__) - - -def get_node_depth(node: Node) -> int: - i = 0 - cur_node = node - while cur_node.parent != node.document: - cur_node = cur_node.parent - i += 1 - return i - - -def register_sections_as_label(app: Sphinx, document: Node) -> None: - docname = app.env.docname - - for pattern in app.config.autosectionlabel_skip_docs: - if fnmatch(docname, pattern): - return None - - domain = cast(StandardDomain, app.env.get_domain("std")) - for node in document.traverse(nodes.section): - if ( - app.config.autosectionlabel_maxdepth - and get_node_depth(node) >= app.config.autosectionlabel_maxdepth - ): - continue - labelid = node["ids"][0] - - title = cast(nodes.title, node[0]) - ref_name = getattr(title, "rawsource", title.astext()) - if app.config.autosectionlabel_prefix_document: - name = nodes.fully_normalize_name(docname + ":" + ref_name) - else: - name = nodes.fully_normalize_name(ref_name) - sectname = clean_astext(title) - - if name in domain.labels: - logger.warning( - __("duplicate label %s, other instance in %s"), - name, - app.env.doc2path(domain.labels[name][0]), - location=node, - type="autosectionlabel", - subtype=docname, - ) - - domain.anonlabels[name] = docname, labelid - domain.labels[name] = docname, labelid, sectname - - -def setup(app: Sphinx) -> dict[str, Any]: - app.add_config_value("autosectionlabel_prefix_document", False, "env") - app.add_config_value("autosectionlabel_maxdepth", None, "env") - app.add_config_value("autosectionlabel_skip_docs", [], "env") - app.connect("doctree-read", register_sections_as_label) - - return { - "version": "builtin", - "parallel_read_safe": True, - "parallel_write_safe": True, - } diff --git a/docs/source/_exts/patched_html_translator.py b/docs/source/_exts/patched_html_translator.py deleted file mode 100644 index e2f8ed9a4..000000000 --- a/docs/source/_exts/patched_html_translator.py +++ /dev/null @@ -1,24 +0,0 @@ -from sphinx.util.docutils import is_html5_writer_available -from sphinx.writers.html import HTMLTranslator -from sphinx.writers.html5 import HTML5Translator - - -class PatchedHTMLTranslator( - HTML5Translator if is_html5_writer_available() else HTMLTranslator -): - def starttag(self, node, tagname, *args, **attrs): - if ( - tagname == "a" - and "target" not in attrs - and ( - "external" in attrs.get("class", "") - or "external" in attrs.get("classes", []) - ) - ): - attrs["target"] = "_blank" - attrs["ref"] = "noopener noreferrer" - return super().starttag(node, tagname, *args, **attrs) - - -def setup(app): - app.set_translator("html", PatchedHTMLTranslator) diff --git a/docs/source/_exts/reactpy_example.py b/docs/source/_exts/reactpy_example.py deleted file mode 100644 index c6b054c07..000000000 --- a/docs/source/_exts/reactpy_example.py +++ /dev/null @@ -1,180 +0,0 @@ -from __future__ import annotations - -import re -from pathlib import Path -from typing import Any - -from docs_app.examples import ( - SOURCE_DIR, - get_example_files_by_name, - get_normalized_example_name, -) -from docutils.parsers.rst import directives -from docutils.statemachine import StringList -from sphinx.application import Sphinx -from sphinx.util.docutils import SphinxDirective -from sphinx_design.tabs import TabSetDirective - - -class WidgetExample(SphinxDirective): - has_content = False - required_arguments = 1 - _next_id = 0 - - option_spec = { - "result-is-default-tab": directives.flag, - "activate-button": directives.flag, - } - - def run(self): - example_name = get_normalized_example_name( - self.arguments[0], - # only used if example name starts with "/" - self.get_source_info()[0], - ) - - show_linenos = "linenos" in self.options - live_example_is_default_tab = "result-is-default-tab" in self.options - activate_result = "activate-button" not in self.options - - ex_files = get_example_files_by_name(example_name) - if not ex_files: - src_file, line_num = self.get_source_info() - msg = f"Missing example named {example_name!r} referenced by document {src_file}:{line_num}" - raise ValueError(msg) - - labeled_tab_items: list[tuple[str, Any]] = [] - if len(ex_files) == 1: - labeled_tab_items.append( - ( - "main.py", - _literal_include( - path=ex_files[0], - linenos=show_linenos, - ), - ) - ) - else: - for path in sorted( - ex_files, key=lambda p: "" if p.name == "main.py" else p.name - ): - labeled_tab_items.append( - ( - path.name, - _literal_include( - path=path, - linenos=show_linenos, - ), - ) - ) - - result_tab_item = ( - "🚀 result", - _interactive_widget( - name=example_name, - with_activate_button=not activate_result, - ), - ) - if live_example_is_default_tab: - labeled_tab_items.insert(0, result_tab_item) - else: - labeled_tab_items.append(result_tab_item) - - return TabSetDirective( - "WidgetExample", - [], - {}, - _make_tab_items(labeled_tab_items), - self.lineno - 2, - self.content_offset, - "", - self.state, - self.state_machine, - ).run() - - -def _make_tab_items(labeled_content_tuples): - tab_items = "" - for label, content in labeled_content_tuples: - tab_items += _tab_item_template.format( - label=label, - content=content.replace("\n", "\n "), - ) - return _string_to_nested_lines(tab_items) - - -def _literal_include(path: Path, linenos: bool): - try: - language = { - ".py": "python", - ".js": "javascript", - ".json": "json", - }[path.suffix] - except KeyError: - msg = f"Unknown extension type {path.suffix!r}" - raise ValueError(msg) from None - - return _literal_include_template.format( - name=str(path.relative_to(SOURCE_DIR)), - language=language, - options=_join_options(_get_file_options(path)), - ) - - -def _join_options(option_strings: list[str]) -> str: - return "\n ".join(option_strings) - - -OPTION_PATTERN = re.compile(r"#\s:[\w-]+:.*") - - -def _get_file_options(file: Path) -> list[str]: - options = [] - - for line in file.read_text().split("\n"): - if not line.strip(): - continue - if not line.startswith("#"): - break - if not OPTION_PATTERN.match(line): - continue - option_string = line[1:].strip() - if option_string: - options.append(option_string) - - return options - - -def _interactive_widget(name, with_activate_button): - return _interactive_widget_template.format( - name=name, - activate_button_opt=":activate-button:" if with_activate_button else "", - ) - - -_tab_item_template = """ -.. tab-item:: {label} - - {content} -""" - - -_interactive_widget_template = """ -.. reactpy-view:: {name} - {activate_button_opt} -""" - - -_literal_include_template = """ -.. literalinclude:: /{name} - :language: {language} - {options} -""" - - -def _string_to_nested_lines(content): - return StringList(content.split("\n")) - - -def setup(app: Sphinx) -> None: - app.add_directive("reactpy", WidgetExample) diff --git a/docs/source/_exts/reactpy_view.py b/docs/source/_exts/reactpy_view.py deleted file mode 100644 index 7a2bf85a4..000000000 --- a/docs/source/_exts/reactpy_view.py +++ /dev/null @@ -1,63 +0,0 @@ -import os -import sys - -print(sys.path) - -from docs_app.examples import get_normalized_example_name -from docutils.nodes import raw -from docutils.parsers.rst import directives -from sphinx.application import Sphinx -from sphinx.util.docutils import SphinxDirective - -_REACTPY_EXAMPLE_HOST = os.environ.get("REACTPY_DOC_EXAMPLE_SERVER_HOST", "") -_REACTPY_STATIC_HOST = os.environ.get("REACTPY_DOC_STATIC_SERVER_HOST", "/docs").rstrip( - "/" -) - - -class IteractiveWidget(SphinxDirective): - has_content = False - required_arguments = 1 - _next_id = 0 - - option_spec = { - "activate-button": directives.flag, - "margin": float, - } - - def run(self): - IteractiveWidget._next_id += 1 - container_id = f"reactpy-widget-{IteractiveWidget._next_id}" - view_id = get_normalized_example_name( - self.arguments[0], - # only used if example name starts with "/" - self.get_source_info()[0], - ) - return [ - raw( - "", - f""" -
-
- -
- """, - format="html", - ) - ] - - -def setup(app: Sphinx) -> None: - app.add_directive("reactpy-view", IteractiveWidget) diff --git a/docs/source/_static/css/furo-theme-overrides.css b/docs/source/_static/css/furo-theme-overrides.css deleted file mode 100644 index a258e025e..000000000 --- a/docs/source/_static/css/furo-theme-overrides.css +++ /dev/null @@ -1,6 +0,0 @@ -.sidebar-container { - width: 18em; -} -.sidebar-brand-text { - display: none; -} diff --git a/docs/source/_static/css/larger-api-margins.css b/docs/source/_static/css/larger-api-margins.css deleted file mode 100644 index f8b75d592..000000000 --- a/docs/source/_static/css/larger-api-margins.css +++ /dev/null @@ -1,7 +0,0 @@ -:is(.data, .function, .class, .exception).py { - margin-top: 3em; -} - -:is(.attribute, .method).py { - margin-top: 1.8em; -} diff --git a/docs/source/_static/css/larger-headings.css b/docs/source/_static/css/larger-headings.css deleted file mode 100644 index 297ab7202..000000000 --- a/docs/source/_static/css/larger-headings.css +++ /dev/null @@ -1,9 +0,0 @@ -h1, -h2, -h3, -h4, -h5, -h6 { - margin-top: 1.5em !important; - font-weight: 900 !important; -} diff --git a/docs/source/_static/css/reactpy-view.css b/docs/source/_static/css/reactpy-view.css deleted file mode 100644 index 56df74970..000000000 --- a/docs/source/_static/css/reactpy-view.css +++ /dev/null @@ -1,43 +0,0 @@ -.interactive { - -webkit-transition: 0.1s ease-out; - -moz-transition: 0.1s ease-out; - -o-transition: 0.1s ease-out; - transition: 0.1s ease-out; -} -.widget-container { - padding: 15px; - overflow: auto; - background-color: var(--color-code-background); - min-height: 75px; -} - -.widget-container .printout { - margin-top: 20px; - border-top: solid 2px var(--color-foreground-border); - padding-top: 20px; -} - -.widget-container > div { - width: 100%; -} - -.enable-widget-button { - padding: 10px; - color: #ffffff !important; - text-transform: uppercase; - text-decoration: none; - background: #526cfe; - border: 2px solid #526cfe !important; - transition: all 0.1s ease 0s; - box-shadow: 0 5px 10px var(--color-foreground-border); -} -.enable-widget-button:hover { - color: #526cfe !important; - background: #ffffff; - transition: all 0.1s ease 0s; -} -.enable-widget-button:focus { - outline: 0 !important; - transform: scale(0.98); - transition: all 0.1s ease 0s; -} diff --git a/docs/source/_static/css/sphinx-design-overrides.css b/docs/source/_static/css/sphinx-design-overrides.css deleted file mode 100644 index 767d9d16c..000000000 --- a/docs/source/_static/css/sphinx-design-overrides.css +++ /dev/null @@ -1,14 +0,0 @@ -.sd-card-body { - display: flex; - flex-direction: column; - align-items: stretch; -} - -.sd-tab-content .highlight pre { - max-height: 700px; - overflow: auto; -} - -.sd-card-title .sd-badge { - font-size: 1em; -} diff --git a/docs/source/_static/css/widget-output-css-overrides.css b/docs/source/_static/css/widget-output-css-overrides.css deleted file mode 100644 index 7ddf1a792..000000000 --- a/docs/source/_static/css/widget-output-css-overrides.css +++ /dev/null @@ -1,8 +0,0 @@ -.widget-container h1, -.widget-container h2, -.widget-container h3, -.widget-container h4, -.widget-container h5, -.widget-container h6 { - margin: 0 !important; -} diff --git a/docs/source/_static/install-and-run-reactpy.gif b/docs/source/_static/install-and-run-reactpy.gif deleted file mode 100644 index 49d431341..000000000 Binary files a/docs/source/_static/install-and-run-reactpy.gif and /dev/null differ diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst deleted file mode 100644 index f739ce980..000000000 --- a/docs/source/about/changelog.rst +++ /dev/null @@ -1,1124 +0,0 @@ -Changelog -========= - -.. note:: - - The ReactPy team manages their short and long term plans with `GitHub Projects - `__. If you have questions about what - the team are working on, or have feedback on how issues should be prioritized, feel - free to :discussion-type:`open up a discussion `. - -All notable changes to this project will be recorded in this document. The style of -which is based on `Keep a Changelog `__. The versioning -scheme for the project adheres to `Semantic Versioning `__. For -more info, see the :ref:`Contributor Guide `. - - -.. INSTRUCTIONS FOR CHANGELOG CONTRIBUTORS -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -.. If you're adding a changelog entry, be sure to read the "Creating a Changelog Entry" -.. section of the documentation before doing so for instructions on how to adhere to the -.. "Keep a Changelog" style guide (https://keepachangelog.com). - -Unreleased ----------- - -No changes. - - -v1.0.0 ------- -:octicon:`milestone` *released on 2023-03-14* - -No changes. - - -v1.0.0-a6 ---------- -:octicon:`milestone` *released on 2023-02-23* - -**Fixed** - -- :pull:`936` - remaining issues from :pull:`934` - - -v1.0.0-a5 ---------- -:octicon:`milestone` *released on 2023-02-21* - -**Fixed** - -- :pull:`934` - minor issues with camelCase rewrite CLI utility - - -v1.0.0-a4 ---------- -:octicon:`milestone` *released on 2023-02-21* - -**Changed** - -- :pull:`919` - Reverts :pull:`841` as per the conclusion in :discussion:`916`. but - preserves the ability to declare attributes with snake_case. - -**Deprecated** - -- :pull:`919` - Declaration of keys via keyword arguments in standard elements. A script - has been added to automatically convert old usages where possible. - - -v1.0.0-a3 ---------- -:octicon:`milestone` *released on 2023-02-02* - -**Fixed** - -- :pull:`908` - minor type hint issue with ``VdomDictConstructor`` - -**Removed** - -- :pull:`907` - accidental import of reactpy.testing - - -v1.0.0-a2 ---------- -:octicon:`milestone` *released on 2023-01-31* - -**Reverted** - -- :pull:`901` - reverts :pull:`886` due to :issue:`896` - -**Fixed** - -- :issue:`896` - Stale event handlers after disconnect/reconnect cycle -- :issue:`898` - Fixed CLI not registered as entry point - - -v1.0.0-a1 ---------- -:octicon:`milestone` *released on 2023-01-28* - -**Changed** - -- :pull:`841` - Revamped element constructor interface. Now instead of passing a - dictionary of attributes to element constructors, attributes are declared using - keyword arguments. For example, instead of writing: - - .. code-block:: - - html.div({"className": "some-class"}, "some", "text") - - You now should write: - - .. code-block:: - - html.div("some", "text", class_name="some-class") - - .. note:: - - All attributes are written using ``snake_case``. - - In conjunction, with these changes, ReactPy now supplies a command line utility that - makes a "best effort" attempt to automatically convert code to the new API. Usage of - this utility is as follows: - - .. code-block:: bash - - reactpy update-html-usages [PATHS] - - Where ``[PATHS]`` is any number of directories or files that should be rewritten. - - .. warning:: - - After running this utility, code comments and formatting may have been altered. It's - recommended that you run a code formatting tool like `Black - `__ and manually review and replace any comments that - may have been moved. - -**Fixed** - -- :issue:`755` - unification of component and VDOM constructor interfaces. See above. - - -v0.44.0 -------- -:octicon:`milestone` *released on 2023-01-27* - -**Deprecated** - -- :pull:`876` - ``reactpy.widgets.hotswap``. The function has no clear uses outside of some - internal applications. For this reason it has been deprecated. - -**Removed** - -- :pull:`886` - Ability to access element value from events via `event['value']` key. - Instead element value should be accessed via `event['target']['value']`. Originally - deprecated in :ref:`v0.34.0`. -- :pull:`886` - old misspelled option ``reactpy.config.REACTPY_WED_MODULES_DIR``. Originally - deprecated in :ref:`v0.36.1`. - - -v0.43.0 -------- -:octicon:`milestone` *released on 2023-01-09* - -**Deprecated** - -- :pull:`870` - ``ComponentType.should_render()``. This method was implemented based on - reading the React/Preact source code. As it turns out though it seems like it's mostly - a vestige from the fact that both these libraries still support class-based - components. The ability for components to not render also caused several bugs. - -**Fixed** - -- :issue:`846` - Nested context does no update value if outer context should not render. -- :issue:`847` - Detached model state on render of context consumer if unmounted and - context value does not change. - - -v0.42.0 -------- -:octicon:`milestone` *released on 2022-12-02* - -**Added** - -- :pull:`835` - Ability to customize the ```` element of ReactPy's built-in client. -- :pull:`835` - ``vdom_to_html`` utility function. -- :pull:`843` - Ability to subscribe to changes that are made to mutable options. -- :pull:`832` - ``del_html_head_body_transform`` to remove ````, ````, and ```` while preserving children. -- :pull:`699` - Support for form element serialization - -**Fixed** - -- :issue:`582` - ``REACTPY_DEBUG_MODE`` is now mutable and can be changed at runtime -- :pull:`832` - Fix ``html_to_vdom`` improperly removing ````, ````, and ```` nodes. - -**Removed** - -- :pull:`832` - Removed ``reactpy.html.body`` as it is currently unusable due to technological limitations, and thus not needed. -- :pull:`840` - remove ``REACTPY_FEATURE_INDEX_AS_DEFAULT_KEY`` option -- :pull:`835` - ``serve_static_files`` option from backend configuration - -**Deprecated** - -- :commit:`8f3785b` - Deprecated ``module_from_template`` - -v0.41.0 -------- -:octicon:`milestone` *released on 2022-11-01* - -**Changed** - -- :pull:`823` - The hooks ``use_location`` and ``use_scope`` are no longer - implementation specific and are now available as top-level imports. Instead of each - backend defining these hooks, backends establish a ``ConnectionContext`` with this - information. -- :pull:`824` - ReactPy's built-in backend server now expose the following routes: - - - ``/_reactpy/assets/`` - - ``/_reactpy/stream/`` - - ``/_reactpy/modules/`` - - ``//`` - - This should allow the browser to cache static resources. Even if your ``url_prefix`` - is ``/_reactpy``, your app should still work as expected. Though if you're using - ``reactpy-router``, ReactPy's server routes will always take priority. -- :pull:`824` - Backend implementations now strip any URL prefix in the pathname for - ``use_location``. -- :pull:`827` - ``use_state`` now returns a named tuple with ``value`` and ``set_value`` - fields. This is convenient for adding type annotations if the initial state value is - not the same as the values you might pass to the state setter. Where previously you - might have to do something like: - - .. code-block:: - - value: int | None = None - value, set_value = use_state(value) - - Now you can annotate your state using the ``State`` class: - - .. code-block:: - - state: State[int | None] = use_state(None) - - # access value and setter - state.value - state.set_value - - # can still destructure if you need to - value, set_value = state - -**Added** - -- :pull:`823` - There is a new ``use_connection`` hook which returns a ``Connection`` - object. This ``Connection`` object contains a ``location`` and ``scope``, along with - a ``carrier`` which is unique to each backend implementation. - - -v0.40.2 -------- -:octicon:`milestone` *released on 2022-09-13* - -**Changed** - -- :pull:`809` - Avoid the use of JSON patch for diffing models. - - -v0.40.1 -------- -:octicon:`milestone` *released on 2022-09-11* - -**Fixed** - -- :issue:`806` - Child models after a component fail to render - - -v0.40.0 (yanked) ----------------- -:octicon:`milestone` *released on 2022-08-13* - -**Fixed** - -- :issue:`777` - Fix edge cases where ``html_to_vdom`` can fail to convert HTML -- :issue:`789` - Conditionally rendered components cannot use contexts -- :issue:`773` - Use strict equality check for text, numeric, and binary types in hooks -- :issue:`801` - Accidental mutation of old model causes invalid JSON Patch - -**Changed** - -- :pull:`123` - set default timeout on playwright page for testing -- :pull:`787` - Track contexts in hooks as state -- :pull:`787` - remove non-standard ``name`` argument from ``create_context`` - -**Added** - -- :pull:`123` - ``asgiref`` as a dependency -- :pull:`795` - ``lxml`` as a dependency - - -v0.39.0 -------- -:octicon:`milestone` *released on 2022-06-20* - -**Fixed** - -- :pull:`763` - ``No module named 'reactpy.server'`` from ``reactpy.run`` -- :pull:`749` - Setting appropriate MIME type for web modules in `sanic` server implementation - -**Changed** - -- :pull:`763` - renamed various: - - - ``reactpy.testing.server -> reactpy.testing.backend`` - - ``ServerFixture -> BackendFixture`` - - ``DisplayFixture.server -> DisplayFixture.backend`` - -- :pull:`765` - ``exports_default`` parameter is removed from ``module_from_template``. - -**Added** - -- :pull:`765` - ability to specify versions with module templates (e.g. - ``module_from_template("react@^17.0.0", ...)``). - - -v0.38.1 -------- -:octicon:`milestone` *released on 2022-04-15* - -**Fixed** - -- `reactive-python/reactpy-jupyter#22 `__ - - a missing file extension was causing a problem with WebPack. - - -v0.38.0 -------- -:octicon:`milestone` *released on 2022-04-15* - -No changes. - - -v0.38.0-a4 ----------- -:octicon:`milestone` *released on 2022-04-15* - -**Added** - -- :pull:`733` - ``use_debug_value`` hook - -**Changed** - -- :pull:`733` - renamed ``assert_reactpy_logged`` testing util to ``assert_reactpy_did_log`` - - -v0.38.0-a3 ----------- -:octicon:`milestone` *released on 2022-04-15* - -**Changed** - -- :pull:`730` - Layout context management is not async - - -v0.38.0-a2 ----------- -:octicon:`milestone` *released on 2022-04-14* - -**Added** - -- :pull:`721` - Implement ``use_location()`` hook. Navigating to any route below the - root of the application will be reflected in the ``location.pathname``. This operates - in concert with how ReactPy's configured routes have changed. This will ultimately work - towards resolving :issue:`569`. - -**Changed** - -- :pull:`721` - The routes ReactPy configures on apps have changed - - .. code-block:: text - - prefix/_api/modules/* web modules - prefix/_api/stream websocket endpoint - prefix/* client react app - - This means that ReactPy's client app is available at any route below the configured - ``url_prefix`` besides ``prefix/_api``. The ``_api`` route will likely remain a route - which is reserved by ReactPy. The route navigated to below the ``prefix`` will be shown - in ``use_location``. - -- :pull:`721` - ReactPy's client now uses Preact instead of React - -- :pull:`726` - Renamed ``reactpy.server`` to ``reactpy.backend``. Other references to "server - implementations" have been renamed to "backend implementations" throughout the - documentation and code. - -**Removed** - -- :pull:`721` - ``redirect_root`` server option - - -v0.38.0-a1 ----------- -:octicon:`milestone` *released on 2022-03-27* - -**Changed** - -- :pull:`703` - How ReactPy integrates with servers. ``reactpy.run`` no longer accepts an app - instance to discourage use outside of testing. ReactPy's server implementations now - provide ``configure()`` functions instead. ``reactpy.testing`` has been completely - reworked in order to support async web drivers -- :pull:`703` - ``PerClientStateServer`` has been functionally replaced by ``configure`` - -**Added** - -- :issue:`669` - Access to underlying server requests via contexts - -**Removed** - -- :issue:`669` - Removed ``reactpy.widgets.multiview`` since basic routing view ``use_scope`` is - now possible as well as all ``SharedClientStateServer`` implementations. - -**Fixed** - -- :issue:`591` - ReactPy's test suite no longer uses sync web drivers -- :issue:`678` - Updated Sanic requirement to ``>=21`` -- :issue:`657` - How we advertise ``reactpy.run`` - - -v0.37.2 -------- -:octicon:`milestone` *released on 2022-03-27* - -**Changed** - -- :pull:`701` - The name of ``proto`` modules to ``types`` and added a top level - ``reactpy.types`` module - -**Fixed** - -- :pull:`716` - A typo caused ReactPy to use the insecure ``ws`` web-socket protocol on - pages loaded with ``https`` instead of the secure ``wss`` protocol - - -v0.37.1 -------- -:octicon:`milestone` *released on 2022-03-05* - -No changes. - - -v0.37.1-a2 ----------- -:octicon:`milestone` *released on 2022-03-02* - -**Fixed:** - -- :issue:`684` - Revert :pull:`694` and by making ``value`` uncontrolled client-side - - -v0.37.1-a1 ----------- -:octicon:`milestone` *released on 2022-02-28* - -**Fixed:** - -- :issue:`684` - ``onChange`` event for inputs missing key strokes - - -v0.37.0 -------- -:octicon:`milestone` *released on 2022-02-27* - -**Added:** - -- :issue:`682` - Support for keys in HTML fragments -- :pull:`585` - Use Context Hook - -**Fixed:** - -- :issue:`690` - React warning about set state in unmounted component -- :pull:`688` - Missing reset of schedule_render_later flag - ----- - -Releases below do not use the "Keep a Changelog" style guidelines. - ----- - -v0.36.3 -------- -:octicon:`milestone` *released on 2022-02-18* - -Misc bug fixes along with a minor improvement that allows components to return ``None`` -to render nothing. - -**Closed Issues** - -- All child states wiped upon any child key change - :issue:`652` -- Allow NoneType returns within components - :issue:`538` - -**Merged Pull Requests** - -- fix #652 - :pull:`672` -- Fix 663 - :pull:`667` - - -v0.36.2 -------- -:octicon:`milestone` *released on 2022-02-02* - -Hot fix for newly introduced ``DeprecatedOption``: - -- :commit:`c146dfb264cbc3d2256a62efdfe9ccf62c795b01` - - -v0.36.1 -------- -:octicon:`milestone` *released on 2022-02-02* - -Includes bug fixes and renames the configuration option ``REACTPY_WED_MODULES_DIR`` to -``REACTPY_WEB_MODULES_DIR`` with a corresponding deprecation warning. - -**Closed Issues** - -- Fix Key Error When Cleaning Up Event Handlers - :issue:`640` -- Update Script Tag Behavior - :issue:`628` - -**Merged Pull Requests** - -- mark old state as None if unmounting - :pull:`641` -- rename REACTPY_WED_MODULES_DIR to REACTPY_WEB_MODULES_DIR - :pull:`638` - - -v0.36.0 -------- -:octicon:`milestone` *released on 2022-01-30* - -This release includes an important fix for errors produced after :pull:`623` was merged. -In addition there is not a new ``http.script`` element which can behave similarly to a -standard HTML `` diff --git a/docs/source/guides/getting-started/_static/embed-reactpy-view/index.html b/docs/source/guides/getting-started/_static/embed-reactpy-view/index.html deleted file mode 100644 index 146d715e4..000000000 --- a/docs/source/guides/getting-started/_static/embed-reactpy-view/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Example App - - -

This is an Example App

-

Just below is an embedded ReactPy view...

-
- - - diff --git a/docs/source/guides/getting-started/_static/embed-reactpy-view/main.py b/docs/source/guides/getting-started/_static/embed-reactpy-view/main.py deleted file mode 100644 index 6e3687f27..000000000 --- a/docs/source/guides/getting-started/_static/embed-reactpy-view/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from sanic import Sanic -from sanic.response import file - -from reactpy import component, html -from reactpy.backend.sanic import Options, configure - -app = Sanic("MyApp") - - -@app.route("/") -async def index(request): - return await file("index.html") - - -@component -def ReactPyView(): - return html.code("This text came from an ReactPy App") - - -configure(app, ReactPyView, Options(url_prefix="/_reactpy")) - -app.run(host="127.0.0.1", port=5000) diff --git a/docs/source/guides/getting-started/_static/embed-reactpy-view/screenshot.png b/docs/source/guides/getting-started/_static/embed-reactpy-view/screenshot.png deleted file mode 100644 index 7439c83cf..000000000 Binary files a/docs/source/guides/getting-started/_static/embed-reactpy-view/screenshot.png and /dev/null differ diff --git a/docs/source/guides/getting-started/_static/logo-django.svg b/docs/source/guides/getting-started/_static/logo-django.svg deleted file mode 100644 index 1538f0817..000000000 --- a/docs/source/guides/getting-started/_static/logo-django.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - -]> - - - - - - - - - - - - diff --git a/docs/source/guides/getting-started/_static/logo-jupyter.svg b/docs/source/guides/getting-started/_static/logo-jupyter.svg deleted file mode 100644 index fb2921a41..000000000 --- a/docs/source/guides/getting-started/_static/logo-jupyter.svg +++ /dev/null @@ -1,88 +0,0 @@ - -logo.svg -Created using Figma 0.90 - - - - - - - - - - - - - - - - - - diff --git a/docs/source/guides/getting-started/_static/logo-plotly.svg b/docs/source/guides/getting-started/_static/logo-plotly.svg deleted file mode 100644 index 3dd95459a..000000000 --- a/docs/source/guides/getting-started/_static/logo-plotly.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/docs/source/guides/getting-started/_static/reactpy-in-jupyterlab.gif b/docs/source/guides/getting-started/_static/reactpy-in-jupyterlab.gif deleted file mode 100644 index b420ecd8c..000000000 Binary files a/docs/source/guides/getting-started/_static/reactpy-in-jupyterlab.gif and /dev/null differ diff --git a/docs/source/guides/getting-started/_static/shared-client-state-server-slider.gif b/docs/source/guides/getting-started/_static/shared-client-state-server-slider.gif deleted file mode 100644 index 61bb8295f..000000000 Binary files a/docs/source/guides/getting-started/_static/shared-client-state-server-slider.gif and /dev/null differ diff --git a/docs/source/guides/getting-started/index.rst b/docs/source/guides/getting-started/index.rst deleted file mode 100644 index dd210be60..000000000 --- a/docs/source/guides/getting-started/index.rst +++ /dev/null @@ -1,123 +0,0 @@ -Getting Started -=============== - -.. toctree:: - :hidden: - - installing-reactpy - running-reactpy - -.. dropdown:: :octicon:`bookmark-fill;2em` What You'll Learn - :color: info - :animate: fade-in - :open: - - .. grid:: 1 2 2 2 - - .. grid-item-card:: :octicon:`tools` Installing ReactPy - :link: installing-reactpy - :link-type: doc - - Learn how ReactPy can be installed in a variety of different ways - with - different web servers and even in different frameworks. - - .. grid-item-card:: :octicon:`play` Running ReactPy - :link: running-reactpy - :link-type: doc - - See how ReactPy can be run with a variety of different production servers or be - added to existing applications. - -The fastest way to get started with ReactPy is to try it out in a `Juptyer Notebook -`__. -If you want to use a Notebook to work through the examples shown in this documentation, -you'll need to replace calls to ``reactpy.run(App)`` with a line at the end of each cell -that constructs the ``App()`` in question. If that doesn't make sense, the introductory -notebook linked below will demonstrate how to do this: - -.. card:: - :link: https://mybinder.org/v2/gh/reactive-python/reactpy-jupyter/main?urlpath=lab/tree/notebooks/introduction.ipynb - - .. image:: _static/reactpy-in-jupyterlab.gif - :scale: 72% - :align: center - - -Section 1: Installing ReactPy ------------------------------ - -The next fastest option is to install ReactPy along with a supported server (like -``starlette``) with ``pip``: - -.. code-block:: bash - - pip install "reactpy[starlette]" - -To check that everything is working you can run the sample application: - -.. code-block:: bash - - python -c "import reactpy; reactpy.run(reactpy.sample.SampleApp)" - -.. note:: - - This launches a simple development server which is good enough for testing, but - probably not what you want to use in production. When deploying in production, - there's a number of different ways of :ref:`running ReactPy
`. - -You should then see a few log messages: - -.. code-block:: text - - 2022-03-27T11:58:59-0700 | WARNING | You are running a development server. Change this before deploying in production! - 2022-03-27T11:58:59-0700 | INFO | Running with 'Starlette' at http://127.0.0.1:8000 - -The second log message includes a URL indicating where you should go to view the app. -That will usually be http://127.0.0.1:8000. Once you go to that URL you should see -something like this: - -.. card:: - - .. reactpy-view:: _examples/sample_app - -If you get a ``RuntimeError`` similar to the following: - -.. code-block:: text - - Found none of the following builtin server implementations... - -Then be sure you run ``pip install "reactpy[starlette]"`` instead of just ``reactpy``. For -anything else, report your issue in ReactPy's :discussion-type:`discussion forum -`. - -.. card:: - :link: installing-reactpy - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Learn how ReactPy can be installed in a variety of different ways - with different web - servers and even in different frameworks. - - -Section 2: Running ReactPy --------------------------- - -Once you've :ref:`installed ReactPy `, you'll want to learn how to run an -application. Throughout most of the examples in this documentation, you'll see the -:func:`~reactpy.backend.utils.run` function used. While it's convenient tool for -development it shouldn't be used in production settings - it's slow, and could leak -secrets through debug log messages. - -.. reactpy:: _examples/hello_world - -.. card:: - :link: running-reactpy - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - See how ReactPy can be run with a variety of different production servers or be - added to existing applications. diff --git a/docs/source/guides/getting-started/installing-reactpy.rst b/docs/source/guides/getting-started/installing-reactpy.rst deleted file mode 100644 index 0b2ffc28a..000000000 --- a/docs/source/guides/getting-started/installing-reactpy.rst +++ /dev/null @@ -1,121 +0,0 @@ -Installing ReactPy -================== - -You will typically ``pip`` install ReactPy to alongside one of it's natively supported -backends. For example, if we want to run ReactPy using the `Starlette -`__ backend you would run - -.. code-block:: bash - - pip install "reactpy[starlette]" - -If you want to install a "pure" version of ReactPy **without a backend implementation** -you can do so without any installation extras. You might do this if you wanted to -:ref:`use a custom backend ` or if you wanted to manually pin -the dependencies for your chosen backend: - -.. code-block:: bash - - pip install reactpy - - -Native Backends ---------------- - -ReactPy includes built-in support for a variety backend implementations. To install the -required dependencies for each you should substitute ``starlette`` from the ``pip -install`` command above with one of the options below: - -- ``fastapi`` - https://fastapi.tiangolo.com -- ``flask`` - https://palletsprojects.com/p/flask/ -- ``sanic`` - https://sanicframework.org -- ``starlette`` - https://www.starlette.io/ -- ``tornado`` - https://www.tornadoweb.org/en/stable/ - -If you need to, you can install more than one option by separating them with commas: - -.. code-block:: bash - - pip install "reactpy[fastapi,flask,sanic,starlette,tornado]" - -Once this is complete you should be able to :ref:`run ReactPy ` with your -chosen implementation. - - -Other Backends --------------- - -While ReactPy can run in a variety of contexts, sometimes frameworks require extra work in -order to integrate with them. In these cases, the ReactPy team distributes bindings for -those frameworks as separate Python packages. For documentation on how to install and -run ReactPy in these supported frameworks, follow the links below: - -.. raw:: html - - - -.. role:: transparent-text-color - -.. We add transparent-text-color to the text so it's not visible, but it's still -.. searchable. - -.. grid:: 3 - - .. grid-item-card:: - :link: https://github.com/reactive-python/reactpy-django - :img-background: _static/logo-django.svg - :class-card: card-logo-image - - :transparent-text-color:`Django` - - .. grid-item-card:: - :link: https://github.com/reactive-python/reactpy-jupyter - :img-background: _static/logo-jupyter.svg - :class-card: card-logo-image - - :transparent-text-color:`Jupyter` - - .. grid-item-card:: - :link: https://github.com/reactive-python/reactpy-dash - :img-background: _static/logo-plotly.svg - :class-card: card-logo-image - - :transparent-text-color:`Plotly Dash` - - -For Development ---------------- - -If you want to contribute to the development of ReactPy or modify it, you'll want to -install a development version of ReactPy. This involves cloning the repository where ReactPy's -source is maintained, and setting up a :ref:`development environment`. From there you'll -be able to modifying ReactPy's source code and :ref:`run its tests ` to -ensure the modifications you've made are backwards compatible. If you want to add a new -feature to ReactPy you should write your own test that validates its behavior. - -If you have questions about how to modify ReactPy or help with its development, be sure to -:discussion:`start a discussion `. The ReactPy team are always -excited to :ref:`welcome ` new contributions and contributors -of all kinds - -.. card:: - :link: /about/contributor-guide - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Learn more about how to contribute to the development of ReactPy. diff --git a/docs/source/guides/getting-started/running-reactpy.rst b/docs/source/guides/getting-started/running-reactpy.rst deleted file mode 100644 index 8abbd574f..000000000 --- a/docs/source/guides/getting-started/running-reactpy.rst +++ /dev/null @@ -1,221 +0,0 @@ -Running ReactPy -=============== - -The simplest way to run ReactPy is with the :func:`~reactpy.backend.utils.run` function. This -is the method you'll see used throughout this documentation. However, this executes your -application using a development server which is great for testing, but probably not what -if you're :ref:`deploying in production `. Below are some -more robust and performant ways of running ReactPy with various supported servers. - - -Running ReactPy in Production ------------------------------ - -The first thing you'll need to do if you want to run ReactPy in production is choose a -backend implementation and follow its documentation on how to create and run an -application. This is the backend :ref:`you probably chose ` when -installing ReactPy. Then you'll need to configure that application with an ReactPy view. We -show the basics of how to set up, and then run, each supported backend below, but all -implementations will follow a pattern similar to the following: - -.. code-block:: - - from my_chosen_backend import Application - - from reactpy import component, html - from reactpy.backend.my_chosen_backend import configure - - - @component - def HelloWorld(): - return html.h1("Hello, world!") - - - app = Application() - configure(app, HelloWorld) - -You'll then run this ``app`` using an `ASGI `__ -or `WSGI `__ server from the command line. - - -Running with `FastAPI `__ -....................................................... - -.. reactpy:: _examples/run_fastapi - -Then assuming you put this in ``main.py``, you can run the ``app`` using the `Uvicorn -`__ ASGI server: - -.. code-block:: bash - - uvicorn main:app - - -Running with `Flask `__ -............................................................. - -.. reactpy:: _examples/run_flask - -Then assuming you put this in ``main.py``, you can run the ``app`` using the `Gunicorn -`__ WSGI server: - -.. code-block:: bash - - gunicorn main:app - - -Running with `Sanic `__ -................................................... - -.. reactpy:: _examples/run_sanic - -Then assuming you put this in ``main.py``, you can run the ``app`` using Sanic's builtin -server: - -.. code-block:: bash - - sanic main.app - - -Running with `Starlette `__ -...................................................... - -.. reactpy:: _examples/run_starlette - -Then assuming you put this in ``main.py``, you can run the application using the -`Uvicorn `__ ASGI server: - -.. code-block:: bash - - uvicorn main:app - - -Running with `Tornado `__ -................................................................ - -.. reactpy:: _examples/run_tornado - -Tornado is run using it's own builtin server rather than an external WSGI or ASGI -server. - - -Running ReactPy in Debug Mode ------------------------------ - -ReactPy provides a debug mode that is turned off by default. This can be enabled when you -run your application by setting the ``REACTPY_DEBUG_MODE`` environment variable. - -.. tab-set:: - - .. tab-item:: Unix Shell - - .. code-block:: - - export REACTPY_DEBUG_MODE=1 - python my_reactpy_app.py - - .. tab-item:: Command Prompt - - .. code-block:: text - - set REACTPY_DEBUG_MODE=1 - python my_reactpy_app.py - - .. tab-item:: PowerShell - - .. code-block:: powershell - - $env:REACTPY_DEBUG_MODE = "1" - python my_reactpy_app.py - -.. danger:: - - Leave debug mode off in production! - -Among other things, running in this mode: - -- Turns on debug log messages -- Adds checks to ensure the :ref:`VDOM` spec is adhered to -- Displays error messages that occur within your app - -Errors will be displayed where the uppermost component is located in the view: - -.. reactpy:: _examples/debug_error_example - - -Backend Configuration Options ------------------------------ - -ReactPy's various backend implementations come with ``Options`` that can be passed to their -respective ``configure()`` functions in the following way: - -.. code-block:: - - from reactpy.backend. import configure, Options - - configure(app, MyComponent, Options(...)) - -To learn more read about the options for your chosen backend ````: - -- :class:`reactpy.backend.fastapi.Options` -- :class:`reactpy.backend.flask.Options` -- :class:`reactpy.backend.sanic.Options` -- :class:`reactpy.backend.starlette.Options` -- :class:`reactpy.backend.tornado.Options` - - -Embed in an Existing Webpage ----------------------------- - -ReactPy provides a Javascript client called ``@reactpy/client`` that can be used to embed -ReactPy views within an existing applications. This is actually how the interactive -examples throughout this documentation have been created. You can try this out by -embedding one the examples from this documentation into your own webpage: - -.. tab-set:: - - .. tab-item:: HTML - - .. literalinclude:: _static/embed-doc-ex.html - :language: html - - .. tab-item:: â–ļī¸ Result - - .. raw:: html - :file: _static/embed-doc-ex.html - -.. note:: - - For more information on how to use the client see the :ref:`Javascript API` - reference. Or if you need to, your can :ref:`write your own backend implementation - `. - -As mentioned though, this is connecting to the server that is hosting this -documentation. If you want to connect to a view from your own server, you'll need to -change the URL above to one you provide. One way to do this might be to add to an -existing application. Another would be to run ReactPy in an adjacent web server instance -that you coordinate with something like `NGINX `__. For the sake -of simplicity, we'll assume you do something similar to the following in an existing -Python app: - -.. tab-set:: - - .. tab-item:: main.py - - .. literalinclude:: _static/embed-reactpy-view/main.py - :language: python - - .. tab-item:: index.html - - .. literalinclude:: _static/embed-reactpy-view/index.html - :language: html - -After running ``python main.py``, you should be able to navigate to -``http://127.0.0.1:8000/index.html`` and see: - -.. card:: - :text-align: center - - .. image:: _static/embed-reactpy-view/screenshot.png - :width: 500px - diff --git a/docs/source/guides/managing-state/combining-contexts-and-reducers/index.rst b/docs/source/guides/managing-state/combining-contexts-and-reducers/index.rst deleted file mode 100644 index b9f274f0a..000000000 --- a/docs/source/guides/managing-state/combining-contexts-and-reducers/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -Combining Contexts and Reducers 🚧 -================================== - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/managing-state/deeply-sharing-state-with-contexts/index.rst b/docs/source/guides/managing-state/deeply-sharing-state-with-contexts/index.rst deleted file mode 100644 index 4a00caa48..000000000 --- a/docs/source/guides/managing-state/deeply-sharing-state-with-contexts/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -Deeply Sharing State with Contexts 🚧 -===================================== - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/managing-state/how-to-structure-state/index.rst b/docs/source/guides/managing-state/how-to-structure-state/index.rst deleted file mode 100644 index 5092370a5..000000000 --- a/docs/source/guides/managing-state/how-to-structure-state/index.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _Structuring Your State: - -How to Structure State 🚧 -========================= - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/managing-state/index.rst b/docs/source/guides/managing-state/index.rst deleted file mode 100644 index 0578bafdd..000000000 --- a/docs/source/guides/managing-state/index.rst +++ /dev/null @@ -1,127 +0,0 @@ -Managing State -============== - -.. toctree:: - :hidden: - - how-to-structure-state/index - sharing-component-state/index - when-and-how-to-reset-state/index - simplifying-updates-with-reducers/index - deeply-sharing-state-with-contexts/index - combining-contexts-and-reducers/index - -.. dropdown:: :octicon:`bookmark-fill;2em` What You'll Learn - :color: info - :animate: fade-in - :open: - - .. grid:: 1 2 2 2 - - .. grid-item-card:: :octicon:`organization` How to Structure State - :link: how-to-structure-state/index - :link-type: doc - - Make it easy to reason about your application with strategies for organizing - state. - - .. grid-item-card:: :octicon:`link` Sharing Component State - :link: sharing-component-state/index - :link-type: doc - - Allow components to vary vary together, by lifting state into common - parents. - - .. grid-item-card:: :octicon:`light-bulb` When and How to Reset State - :link: when-and-how-to-reset-state/index - :link-type: doc - - Control if and how state is preserved by understanding it's relationship to - the "UI tree". - - .. grid-item-card:: :octicon:`plug` Simplifying Updates with Reducers - :link: simplifying-updates-with-reducers/index - :link-type: doc - - Consolidate state update logic outside your component in a single function, - called a “reducer". - - .. grid-item-card:: :octicon:`broadcast` Deeply Sharing State with Contexts - :link: deeply-sharing-state-with-contexts/index - :link-type: doc - - Instead of passing shared state down deep component trees, bring state into - "contexts" instead. - - .. grid-item-card:: :octicon:`rocket` Combining Contexts and Reducers - :link: combining-contexts-and-reducers/index - :link-type: doc - - You can combine reducers and context together to manage state of a complex - screen. - - -Section 1: How to Structure State ---------------------------------- - -.. note:: - - Under construction 🚧 - - -Section 2: Shared Component State ---------------------------------- - -Sometimes, you want the state of two components to always change together. To do it, -remove state from both of them, move it to their closest common parent, and then pass it -down to them via props. This is known as “lifting state up”, and it’s one of the most -common things you will do writing code with ReactPy. - -In the example below the search input and the list of elements below share the same -state, the state represents the food name. Note how the component ``Table`` gets called -at each change of state. The component is observing the state and reacting to state -changes automatically, just like it would do in React. - -.. reactpy:: sharing-component-state/_examples/synced_inputs - -.. card:: - :link: sharing-component-state/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Allow components to vary vary together, by lifting state into common parents. - - -Section 3: When and How to Reset State --------------------------------------- - -.. note:: - - Under construction 🚧 - - -Section 4: Simplifying Updates with Reducers --------------------------------------------- - -.. note:: - - Under construction 🚧 - - -Section 5: Deeply Sharing State with Contexts ---------------------------------------------- - -.. note:: - - Under construction 🚧 - - - -Section 6: Combining Contexts and Reducers ------------------------------------------- - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/managing-state/sharing-component-state/_examples/filterable_list/data.json b/docs/source/guides/managing-state/sharing-component-state/_examples/filterable_list/data.json deleted file mode 100644 index f977fe9a7..000000000 --- a/docs/source/guides/managing-state/sharing-component-state/_examples/filterable_list/data.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "name": "Sushi", - "description": "Sushi is a traditional Japanese dish of prepared vinegared rice" - }, - { - "name": "Dal", - "description": "The most common way of preparing dal is in the form of a soup to which onions, tomatoes and various spices may be added" - }, - { - "name": "Pierogi", - "description": "Pierogi are filled dumplings made by wrapping unleavened dough around a savoury or sweet filling and cooking in boiling water" - }, - { - "name": "Shish Kebab", - "description": "Shish kebab is a popular meal of skewered and grilled cubes of meat" - }, - { - "name": "Dim sum", - "description": "Dim sum is a large range of small dishes that Cantonese people traditionally enjoy in restaurants for breakfast and lunch" - } -] diff --git a/docs/source/guides/managing-state/sharing-component-state/_examples/filterable_list/main.py b/docs/source/guides/managing-state/sharing-component-state/_examples/filterable_list/main.py deleted file mode 100644 index ca68aedcb..000000000 --- a/docs/source/guides/managing-state/sharing-component-state/_examples/filterable_list/main.py +++ /dev/null @@ -1,44 +0,0 @@ -import json -from pathlib import Path - -from reactpy import component, hooks, html, run - -HERE = Path(__file__) -DATA_PATH = HERE.parent / "data.json" -food_data = json.loads(DATA_PATH.read_text()) - - -@component -def FilterableList(): - value, set_value = hooks.use_state("") - return html.p(Search(value, set_value), html.hr(), Table(value, set_value)) - - -@component -def Search(value, set_value): - def handle_change(event): - set_value(event["target"]["value"]) - - return html.label( - "Search by Food Name: ", - html.input({"value": value, "on_change": handle_change}), - ) - - -@component -def Table(value, set_value): - rows = [] - for row in food_data: - name = html.td(row["name"]) - descr = html.td(row["description"]) - tr = html.tr(name, descr, value) - if not value: - rows.append(tr) - elif value.lower() in row["name"].lower(): - rows.append(tr) - headers = html.tr(html.td(html.b("name")), html.td(html.b("description"))) - table = html.table(html.thead(headers), html.tbody(rows)) - return table - - -run(FilterableList) diff --git a/docs/source/guides/managing-state/sharing-component-state/_examples/synced_inputs/main.py b/docs/source/guides/managing-state/sharing-component-state/_examples/synced_inputs/main.py deleted file mode 100644 index e8bcdf333..000000000 --- a/docs/source/guides/managing-state/sharing-component-state/_examples/synced_inputs/main.py +++ /dev/null @@ -1,23 +0,0 @@ -from reactpy import component, hooks, html, run - - -@component -def SyncedInputs(): - value, set_value = hooks.use_state("") - return html.p( - Input("First input", value, set_value), - Input("Second input", value, set_value), - ) - - -@component -def Input(label, value, set_value): - def handle_change(event): - set_value(event["target"]["value"]) - - return html.label( - label + " ", html.input({"value": value, "on_change": handle_change}) - ) - - -run(SyncedInputs) diff --git a/docs/source/guides/managing-state/sharing-component-state/index.rst b/docs/source/guides/managing-state/sharing-component-state/index.rst deleted file mode 100644 index 54b61335a..000000000 --- a/docs/source/guides/managing-state/sharing-component-state/index.rst +++ /dev/null @@ -1,38 +0,0 @@ -Sharing Component State -======================= - -.. note:: - - Parts of this document are still under construction 🚧 - -Sometimes, you want the state of two components to always change together. To do it, -remove state from both of them, move it to their closest common parent, and then pass it -down to them via props. This is known as “lifting state up”, and it’s one of the most -common things you will do writing code with ReactPy. - - -Synced Inputs -------------- - -In the code below the two input boxes are synchronized, this happens because they share -state. The state is shared via the parent component ``SyncedInputs``. Check the ``value`` -and ``set_value`` variables. - -.. reactpy:: _examples/synced_inputs - - -Filterable List ----------------- - -In the example below the search input and the list of elements below share the -same state, the state represents the food name. - -Note how the component ``Table`` gets called at each change of state. The -component is observing the state and reacting to state changes automatically, -just like it would do in React. - -.. reactpy:: _examples/filterable_list - -.. note:: - - Try typing a food name in the search bar. diff --git a/docs/source/guides/managing-state/simplifying-updates-with-reducers/index.rst b/docs/source/guides/managing-state/simplifying-updates-with-reducers/index.rst deleted file mode 100644 index 08fce5a69..000000000 --- a/docs/source/guides/managing-state/simplifying-updates-with-reducers/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -Simplifying Updates with Reducers 🚧 -==================================== - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/managing-state/when-and-how-to-reset-state/index.rst b/docs/source/guides/managing-state/when-and-how-to-reset-state/index.rst deleted file mode 100644 index 6a96f4b30..000000000 --- a/docs/source/guides/managing-state/when-and-how-to-reset-state/index.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _When to Reset State: - -When and How to Reset State 🚧 -============================== - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/_static/idom-flow-diagram.svg b/docs/source/guides/understanding-reactpy/_static/idom-flow-diagram.svg deleted file mode 100644 index 9077913ca..000000000 --- a/docs/source/guides/understanding-reactpy/_static/idom-flow-diagram.svg +++ /dev/null @@ -1,383 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - layout - - - - - component - - server - - - - view - - client - - - - event - VDOM diff - VDOM - diff --git a/docs/source/guides/understanding-reactpy/_static/live-examples-in-docs.gif b/docs/source/guides/understanding-reactpy/_static/live-examples-in-docs.gif deleted file mode 100644 index 96a04d68b..000000000 Binary files a/docs/source/guides/understanding-reactpy/_static/live-examples-in-docs.gif and /dev/null differ diff --git a/docs/source/guides/understanding-reactpy/_static/mvc-flow-diagram.svg b/docs/source/guides/understanding-reactpy/_static/mvc-flow-diagram.svg deleted file mode 100644 index a1acbc2cb..000000000 --- a/docs/source/guides/understanding-reactpy/_static/mvc-flow-diagram.svg +++ /dev/null @@ -1,425 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - model - - - - - controller - - server - - - - - model - - - - - view - - client - - - - - event - sync - change - render - diff --git a/docs/source/guides/understanding-reactpy/_static/npm-download-trends.png b/docs/source/guides/understanding-reactpy/_static/npm-download-trends.png deleted file mode 100644 index cf5140b0d..000000000 Binary files a/docs/source/guides/understanding-reactpy/_static/npm-download-trends.png and /dev/null differ diff --git a/docs/source/guides/understanding-reactpy/index.rst b/docs/source/guides/understanding-reactpy/index.rst deleted file mode 100644 index 3e0b2ab72..000000000 --- a/docs/source/guides/understanding-reactpy/index.rst +++ /dev/null @@ -1,17 +0,0 @@ -Understanding ReactPy -===================== - -.. toctree:: - :hidden: - - representing-html - what-are-components - the-rendering-pipeline - why-reactpy-needs-keys - the-rendering-process - layout-render-servers - writing-tests - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/layout-render-servers.rst b/docs/source/guides/understanding-reactpy/layout-render-servers.rst deleted file mode 100644 index 9a7cceb54..000000000 --- a/docs/source/guides/understanding-reactpy/layout-render-servers.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _Layout Render Servers: - -Layout Render Servers 🚧 -======================== - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/representing-html.rst b/docs/source/guides/understanding-reactpy/representing-html.rst deleted file mode 100644 index c2f32ebd9..000000000 --- a/docs/source/guides/understanding-reactpy/representing-html.rst +++ /dev/null @@ -1,76 +0,0 @@ -.. _Representing HTML: - -Representing HTML 🚧 -==================== - -.. note:: - - Under construction 🚧 - -We've already discussed how to construct HTML with ReactPy in a :ref:`previous section `, but we skimmed over the question of the data structure we use to represent -it. Let's reconsider the examples from before - on the top is some HTML and on the -bottom is the corresponding code to create it in ReactPy: - -.. code-block:: html - -
-

My Todo List

-
    -
  • Build a cool new app
  • -
  • Share it with the world!
  • -
-
- -.. testcode:: - - from reactpy import html - - layout = html.div( - html.h1("My Todo List"), - html.ul( - html.li("Build a cool new app"), - html.li("Share it with the world!"), - ) - ) - -Since we've captured our HTML into out the ``layout`` variable, we can inspect what it -contains. And, as it turns out, it holds a dictionary. Printing it produces the -following output: - -.. testsetup:: - - from pprint import pprint - print = lambda *args, **kwargs: pprint(*args, **kwargs, sort_dicts=False) - -.. testcode:: - - assert layout == { - 'tagName': 'div', - 'children': [ - { - 'tagName': 'h1', - 'children': ['My Todo List'] - }, - { - 'tagName': 'ul', - 'children': [ - {'tagName': 'li', 'children': ['Build a cool new app']}, - {'tagName': 'li', 'children': ['Share it with the world!']} - ] - } - ] - } - -This may look complicated, but let's take a moment to consider what's going on here. We -have a series of nested dictionaries that, in some way, represents the HTML structure -given above. If we look at their contents we should see a common form. Each has a -``tagName`` key which contains, as the name would suggest, the tag name of an HTML -element. Then within the ``children`` key is a list that either contains strings or -other dictionaries that represent HTML elements. - -What we're seeing here is called a "virtual document object model" or :ref:`VDOM`. This -is just a fancy way of saying we have a representation of the document object model or -`DOM -`__ -that is not the actual DOM. diff --git a/docs/source/guides/understanding-reactpy/the-rendering-pipeline.rst b/docs/source/guides/understanding-reactpy/the-rendering-pipeline.rst deleted file mode 100644 index cdde27f08..000000000 --- a/docs/source/guides/understanding-reactpy/the-rendering-pipeline.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _The Rendering Pipeline: - -The Rendering Pipeline 🚧 -========================= - -.. talk about layouts and dispatchers - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/the-rendering-process.rst b/docs/source/guides/understanding-reactpy/the-rendering-process.rst deleted file mode 100644 index 00215a887..000000000 --- a/docs/source/guides/understanding-reactpy/the-rendering-process.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _The Rendering Process: - -The Rendering Process 🚧 -======================== - -.. refer to https://beta.reactjs.org/learn/render-and-commit - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/what-are-components.rst b/docs/source/guides/understanding-reactpy/what-are-components.rst deleted file mode 100644 index 4c22dda13..000000000 --- a/docs/source/guides/understanding-reactpy/what-are-components.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _What Are Components: - -What Are Components? 🚧 -======================= - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/why-reactpy-needs-keys.rst b/docs/source/guides/understanding-reactpy/why-reactpy-needs-keys.rst deleted file mode 100644 index e570b8f41..000000000 --- a/docs/source/guides/understanding-reactpy/why-reactpy-needs-keys.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _Why ReactPy Needs Keys: - -Why ReactPy Needs Keys 🚧 -========================= - -.. note:: - - Under construction 🚧 diff --git a/docs/source/guides/understanding-reactpy/writing-tests.rst b/docs/source/guides/understanding-reactpy/writing-tests.rst deleted file mode 100644 index ffac27df6..000000000 --- a/docs/source/guides/understanding-reactpy/writing-tests.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. _Writing Tests: - -Writing Tests 🚧 -================ - -.. note:: - - Under construction 🚧 diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index 8b21160f6..000000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,206 +0,0 @@ -.. card:: - - This documentation is still under construction 🚧. We welcome your `feedback - `__! - - -ReactPy -======= - -.. toctree:: - :hidden: - :caption: Guides - - guides/getting-started/index - guides/creating-interfaces/index - guides/adding-interactivity/index - guides/managing-state/index - guides/escape-hatches/index - guides/understanding-reactpy/index - -.. toctree:: - :hidden: - :caption: Reference - - reference/browser-events - reference/html-attributes - reference/hooks-api - _auto/apis - reference/javascript-api - reference/specifications - -.. toctree:: - :hidden: - :caption: About - - about/changelog - about/contributor-guide - about/credits-and-licenses - Source Code - Community - -ReactPy is a library for building user interfaces in Python without Javascript. ReactPy -interfaces are made from :ref:`components ` which look and behave -similarly to those found in `ReactJS `__. Designed with simplicity -in mind, ReactPy can be used by those without web development experience while also -being powerful enough to grow with your ambitions. - - -At a Glance ------------ - -To get a rough idea of how to write apps in ReactPy, take a look at the tiny `"hello world" -`__ application below: - -.. reactpy:: guides/getting-started/_examples/hello_world - -.. hint:: - - Try clicking the **🚀 result** tab to see what this displays! - -So what exactly does this code do? First, it imports a few tools from ``reactpy`` that will -get used to describe and execute an application. Then, we create an ``App`` function -which will define the content the application displays. Specifically, it displays a kind -of HTML element called an ``h1`` `section heading -`__. -Importantly though, a ``@component`` decorator has been applied to the ``App`` function -to turn it into a :ref:`component `. Finally, we :ref:`run -` a development web server by passing the ``App`` component to the -``run()`` function. - -.. note:: - - See :ref:`Running ReactPy in Production` to learn how to use a production-grade server - to run ReactPy. - - -Learning ReactPy ----------------- - -This documentation is broken up into chapters and sections that introduce you to -concepts step by step with detailed explanations and lots of examples. You should feel -free to dive into any content that seems interesting. While each chapter assumes -knowledge from those that came before, when you encounter a concept you're unfamiliar -with you should look for links that will help direct you to the place where it was -originally taught. - - -Chapter 1 - :ref:`Getting Started` ------------------------------------ - -If you want to follow along with examples in the sections that follow, you'll want to -start here so you can :ref:`install ReactPy `. This section also contains -more detailed information about how to :ref:`run ReactPy ` in different -contexts. For example, if you want to embed ReactPy into an existing application, or run -ReactPy within a Jupyter Notebook, this is where you can learn how to do those things. - -.. grid:: 1 2 2 2 - - .. grid-item:: - - .. image:: _static/install-and-run-reactpy.gif - - .. grid-item:: - - .. image:: guides/getting-started/_static/reactpy-in-jupyterlab.gif - -.. card:: - :link: guides/getting-started/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Install ReactPy and run it in a variety of different ways - with different web servers - and frameworks. You'll even embed ReactPy into an existing app. - - -Chapter 2 - :ref:`Creating Interfaces` --------------------------------------- - -ReactPy is a Python package for making user interfaces (UI). These interfaces are built -from small elements of functionality like buttons text and images. ReactPy allows you to -combine these elements into reusable :ref:`"components" `. In the -sections that follow you'll learn how these UI elements are created and organized into -components. Then, you'll use this knowledge to create interfaces from raw data: - -.. reactpy:: guides/creating-interfaces/rendering-data/_examples/todo_list_with_keys - -.. card:: - :link: guides/creating-interfaces/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Learn to construct user interfaces from basic HTML elements and reusable components. - - -Chapter 3 - :ref:`Adding Interactivity` ---------------------------------------- - -Components often need to change what’s on the screen as a result of an interaction. For -example, typing into the form should update the input field, clicking a “Comment” button -should bring up a text input field, clicking “Buy” should put a product in the shopping -cart. Components need to “remember” things like the current input value, the current -image, the shopping cart. In ReactPy, this kind of component-specific memory is created and -updated with a "hook" called ``use_state()`` that creates a **state variable** and -**state setter** respectively: - -.. reactpy:: guides/adding-interactivity/components-with-state/_examples/adding_state_variable - -In ReactPy, ``use_state``, as well as any other function whose name starts with ``use``, is -called a "hook". These are special functions that should only be called while ReactPy is -:ref:`rendering `. They let you "hook into" the different -capabilities of ReactPy's components of which ``use_state`` is just one (well get into the -other :ref:`later `). - -.. card:: - :link: guides/adding-interactivity/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Learn how user interfaces can be made to respond to user interaction in real-time. - - -Chapter 4 - :ref:`Managing State` ---------------------------------- - -.. card:: - :link: guides/managing-state/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Under construction 🚧 - - - -Chapter 5 - :ref:`Escape Hatches` ---------------------------------- - -.. card:: - :link: guides/escape-hatches/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Under construction 🚧 - - -Chapter 6 - :ref:`Understanding ReactPy` ----------------------------------------- - -.. card:: - :link: guides/escape-hatches/index - :link-type: doc - - :octicon:`book` Read More - ^^^^^^^^^^^^^^^^^^^^^^^^^ - - Under construction 🚧 - diff --git a/docs/source/reference/_examples/character_movement/main.py b/docs/source/reference/_examples/character_movement/main.py deleted file mode 100644 index 9545b0c0a..000000000 --- a/docs/source/reference/_examples/character_movement/main.py +++ /dev/null @@ -1,73 +0,0 @@ -from pathlib import Path -from typing import NamedTuple - -from reactpy import component, html, run, use_state -from reactpy.widgets import image - -HERE = Path(__file__) -CHARACTER_IMAGE = (HERE.parent / "static" / "bunny.png").read_bytes() - - -class Position(NamedTuple): - x: int - y: int - angle: int - - -def rotate(degrees): - return lambda old_position: Position( - old_position.x, - old_position.y, - old_position.angle + degrees, - ) - - -def translate(x=0, y=0): - return lambda old_position: Position( - old_position.x + x, - old_position.y + y, - old_position.angle, - ) - - -@component -def Scene(): - position, set_position = use_state(Position(100, 100, 0)) - - return html.div( - {"style": {"width": "225px"}}, - html.div( - { - "style": { - "width": "200px", - "height": "200px", - "background_color": "slategray", - } - }, - image( - "png", - CHARACTER_IMAGE, - { - "style": { - "position": "relative", - "left": f"{position.x}px", - "top": f"{position.y}.px", - "transform": f"rotate({position.angle}deg) scale(2, 2)", - } - }, - ), - ), - html.button( - {"on_click": lambda e: set_position(translate(x=-10))}, "Move Left" - ), - html.button( - {"on_click": lambda e: set_position(translate(x=10))}, "Move Right" - ), - html.button({"on_click": lambda e: set_position(translate(y=-10))}, "Move Up"), - html.button({"on_click": lambda e: set_position(translate(y=10))}, "Move Down"), - html.button({"on_click": lambda e: set_position(rotate(-30))}, "Rotate Left"), - html.button({"on_click": lambda e: set_position(rotate(30))}, "Rotate Right"), - ) - - -run(Scene) diff --git a/docs/source/reference/_examples/character_movement/static/bunny.png b/docs/source/reference/_examples/character_movement/static/bunny.png deleted file mode 100644 index ce1f989c5..000000000 Binary files a/docs/source/reference/_examples/character_movement/static/bunny.png and /dev/null differ diff --git a/docs/source/reference/_examples/click_count.py b/docs/source/reference/_examples/click_count.py deleted file mode 100644 index 3ee2c89c5..000000000 --- a/docs/source/reference/_examples/click_count.py +++ /dev/null @@ -1,13 +0,0 @@ -import reactpy - - -@reactpy.component -def ClickCount(): - count, set_count = reactpy.hooks.use_state(0) - - return reactpy.html.button( - {"on_click": lambda event: set_count(count + 1)}, [f"Click count: {count}"] - ) - - -reactpy.run(ClickCount) diff --git a/docs/source/reference/_examples/material_ui_switch.py b/docs/source/reference/_examples/material_ui_switch.py deleted file mode 100644 index 704ae3145..000000000 --- a/docs/source/reference/_examples/material_ui_switch.py +++ /dev/null @@ -1,22 +0,0 @@ -import reactpy - -mui = reactpy.web.module_from_template("react", "@material-ui/core@^5.0", fallback="⌛") -Switch = reactpy.web.export(mui, "Switch") - - -@reactpy.component -def DayNightSwitch(): - checked, set_checked = reactpy.hooks.use_state(False) - - return reactpy.html.div( - Switch( - { - "checked": checked, - "onChange": lambda event, checked: set_checked(checked), - } - ), - "🌞" if checked else "🌚", - ) - - -reactpy.run(DayNightSwitch) diff --git a/docs/source/reference/_examples/matplotlib_plot.py b/docs/source/reference/_examples/matplotlib_plot.py deleted file mode 100644 index 5c4d616fe..000000000 --- a/docs/source/reference/_examples/matplotlib_plot.py +++ /dev/null @@ -1,85 +0,0 @@ -from io import BytesIO - -import matplotlib.pyplot as plt - -import reactpy -from reactpy.widgets import image - - -@reactpy.component -def PolynomialPlot(): - coefficients, set_coefficients = reactpy.hooks.use_state([0]) - - x = list(linspace(-1, 1, 50)) - y = [polynomial(value, coefficients) for value in x] - - return reactpy.html.div( - plot(f"{len(coefficients)} Term Polynomial", x, y), - ExpandableNumberInputs(coefficients, set_coefficients), - ) - - -@reactpy.component -def ExpandableNumberInputs(values, set_values): - inputs = [] - for i in range(len(values)): - - def set_value_at_index(event, index=i): - new_value = float(event["target"]["value"] or 0) - set_values(values[:index] + [new_value] + values[index + 1 :]) - - inputs.append(poly_coef_input(i + 1, set_value_at_index)) - - def add_input(): - set_values([*values, 0]) - - def del_input(): - set_values(values[:-1]) - - return reactpy.html.div( - reactpy.html.div( - "add/remove term:", - reactpy.html.button({"on_click": lambda event: add_input()}, "+"), - reactpy.html.button({"on_click": lambda event: del_input()}, "-"), - ), - inputs, - ) - - -def plot(title, x, y): - fig, axes = plt.subplots() - axes.plot(x, y) - axes.set_title(title) - buffer = BytesIO() - fig.savefig(buffer, format="png") - plt.close(fig) - return image("png", buffer.getvalue()) - - -def poly_coef_input(index, callback): - return reactpy.html.div( - {"style": {"margin-top": "5px"}, "key": index}, - reactpy.html.label( - "C", - reactpy.html.sub(index), - " x X", - reactpy.html.sup(index), - ), - reactpy.html.input({"type": "number", "on_change": callback}), - ) - - -def polynomial(x, coefficients): - return sum(c * (x ** (i + 1)) for i, c in enumerate(coefficients)) - - -def linspace(start, stop, n): - if n == 1: - yield stop - return - h = (stop - start) / (n - 1) - for i in range(n): - yield start + h * i - - -reactpy.run(PolynomialPlot) diff --git a/docs/source/reference/_examples/network_graph.py b/docs/source/reference/_examples/network_graph.py deleted file mode 100644 index 79b1092f3..000000000 --- a/docs/source/reference/_examples/network_graph.py +++ /dev/null @@ -1,40 +0,0 @@ -import random - -import reactpy - -react_cytoscapejs = reactpy.web.module_from_template( - "react", - "react-cytoscapejs", - fallback="⌛", -) -Cytoscape = reactpy.web.export(react_cytoscapejs, "default") - - -@reactpy.component -def RandomNetworkGraph(): - return Cytoscape( - { - "style": {"width": "100%", "height": "200px"}, - "elements": random_network(20), - "layout": {"name": "cose"}, - } - ) - - -def random_network(number_of_nodes): - conns = [] - nodes = [{"data": {"id": 0, "label": 0}}] - - for src_node_id in range(1, number_of_nodes + 1): - tgt_node = random.choice(nodes) - src_node = {"data": {"id": src_node_id, "label": src_node_id}} - - new_conn = {"data": {"source": src_node_id, "target": tgt_node["data"]["id"]}} - - nodes.append(src_node) - conns.append(new_conn) - - return nodes + conns - - -reactpy.run(RandomNetworkGraph) diff --git a/docs/source/reference/_examples/pigeon_maps.py b/docs/source/reference/_examples/pigeon_maps.py deleted file mode 100644 index 1ddf04fdc..000000000 --- a/docs/source/reference/_examples/pigeon_maps.py +++ /dev/null @@ -1,46 +0,0 @@ -import reactpy - -pigeon_maps = reactpy.web.module_from_template("react", "pigeon-maps", fallback="⌛") -Map, Marker = reactpy.web.export(pigeon_maps, ["Map", "Marker"]) - - -@reactpy.component -def MapWithMarkers(): - marker_anchor, add_marker_anchor, remove_marker_anchor = use_set() - - markers = [ - Marker( - { - "anchor": anchor, - "onClick": lambda event, a=anchor: remove_marker_anchor(a), - }, - key=str(anchor), - ) - for anchor in marker_anchor - ] - - return Map( - { - "defaultCenter": (37.774, -122.419), - "defaultZoom": 12, - "height": "300px", - "metaWheelZoom": True, - "onClick": lambda event: add_marker_anchor(tuple(event["latLng"])), - }, - markers, - ) - - -def use_set(initial_value=None): - values, set_values = reactpy.hooks.use_state(initial_value or set()) - - def add_value(lat_lon): - set_values(values.union({lat_lon})) - - def remove_value(lat_lon): - set_values(values.difference({lat_lon})) - - return values, add_value, remove_value - - -reactpy.run(MapWithMarkers) diff --git a/docs/source/reference/_examples/simple_dashboard.py b/docs/source/reference/_examples/simple_dashboard.py deleted file mode 100644 index 66913fc84..000000000 --- a/docs/source/reference/_examples/simple_dashboard.py +++ /dev/null @@ -1,102 +0,0 @@ -import asyncio -import random -import time - -import reactpy -from reactpy.widgets import Input - -victory = reactpy.web.module_from_template( - "react", - "victory-line", - fallback="⌛", - # not usually required (see issue #461 for more info) - unmount_before_update=True, -) -VictoryLine = reactpy.web.export(victory, "VictoryLine") - - -@reactpy.component -def RandomWalk(): - mu = reactpy.hooks.use_ref(0) - sigma = reactpy.hooks.use_ref(1) - - return reactpy.html.div( - RandomWalkGraph(mu, sigma), - reactpy.html.style( - """ - .number-input-container {margin-bottom: 20px} - .number-input-container input {width: 48%;float: left} - .number-input-container input + input {margin-left: 4%} - """ - ), - NumberInput( - "Mean", - mu.current, - mu.set_current, - (-1, 1, 0.01), - ), - NumberInput( - "Standard Deviation", - sigma.current, - sigma.set_current, - (0, 1, 0.01), - ), - ) - - -@reactpy.component -def RandomWalkGraph(mu, sigma): - interval = use_interval(0.5) - data, set_data = reactpy.hooks.use_state([{"x": 0, "y": 0}] * 50) - - @reactpy.hooks.use_effect - async def animate(): - await interval - last_data_point = data[-1] - next_data_point = { - "x": last_data_point["x"] + 1, - "y": last_data_point["y"] + random.gauss(mu.current, sigma.current), - } - set_data(data[1:] + [next_data_point]) - - return VictoryLine( - { - "data": data, - "style": { - "parent": {"width": "100%"}, - "data": {"stroke": "royalblue"}, - }, - } - ) - - -@reactpy.component -def NumberInput(label, value, set_value_callback, domain): - minimum, maximum, step = domain - attrs = {"min": minimum, "max": maximum, "step": step} - - value, set_value = reactpy.hooks.use_state(value) - - def update_value(value): - set_value(value) - set_value_callback(value) - - return reactpy.html.fieldset( - {"class_name": "number-input-container"}, - reactpy.html.legend({"style": {"font-size": "medium"}}, label), - Input(update_value, "number", value, attributes=attrs, cast=float), - Input(update_value, "range", value, attributes=attrs, cast=float), - ) - - -def use_interval(rate): - usage_time = reactpy.hooks.use_ref(time.time()) - - async def interval() -> None: - await asyncio.sleep(rate - (time.time() - usage_time.current)) - usage_time.current = time.time() - - return asyncio.ensure_future(interval()) - - -reactpy.run(RandomWalk) diff --git a/docs/source/reference/_examples/slideshow.py b/docs/source/reference/_examples/slideshow.py deleted file mode 100644 index b490b3feb..000000000 --- a/docs/source/reference/_examples/slideshow.py +++ /dev/null @@ -1,20 +0,0 @@ -import reactpy - - -@reactpy.component -def Slideshow(): - index, set_index = reactpy.hooks.use_state(0) - - def next_image(event): - set_index(index + 1) - - return reactpy.html.img( - { - "src": f"https://picsum.photos/id/{index}/800/300", - "style": {"cursor": "pointer"}, - "on_click": next_image, - } - ) - - -reactpy.run(Slideshow) diff --git a/docs/source/reference/_examples/snake_game.py b/docs/source/reference/_examples/snake_game.py deleted file mode 100644 index 36916410e..000000000 --- a/docs/source/reference/_examples/snake_game.py +++ /dev/null @@ -1,188 +0,0 @@ -import asyncio -import enum -import random -import time - -import reactpy - - -class GameState(enum.Enum): - init = 0 - lost = 1 - won = 2 - play = 3 - - -@reactpy.component -def GameView(): - game_state, set_game_state = reactpy.hooks.use_state(GameState.init) - - if game_state == GameState.play: - return GameLoop(grid_size=6, block_scale=50, set_game_state=set_game_state) - - start_button = reactpy.html.button( - {"on_click": lambda event: set_game_state(GameState.play)}, "Start" - ) - - if game_state == GameState.won: - menu = reactpy.html.div(reactpy.html.h3("You won!"), start_button) - elif game_state == GameState.lost: - menu = reactpy.html.div(reactpy.html.h3("You lost"), start_button) - else: - menu = reactpy.html.div(reactpy.html.h3("Click to play"), start_button) - - menu_style = reactpy.html.style( - """ - .snake-game-menu h3 { - margin-top: 0px !important; - } - """ - ) - - return reactpy.html.div({"class_name": "snake-game-menu"}, menu_style, menu) - - -class Direction(enum.Enum): - ArrowUp = (0, -1) - ArrowLeft = (-1, 0) - ArrowDown = (0, 1) - ArrowRight = (1, 0) - - -@reactpy.component -def GameLoop(grid_size, block_scale, set_game_state): - # we `use_ref` here to capture the latest direction press without any delay - direction = reactpy.hooks.use_ref(Direction.ArrowRight.value) - # capture the last direction of travel that was rendered - last_direction = direction.current - - snake, set_snake = reactpy.hooks.use_state( - [(grid_size // 2 - 1, grid_size // 2 - 1)] - ) - food, set_food = use_snake_food(grid_size, snake) - - grid = create_grid(grid_size, block_scale) - - @reactpy.event(prevent_default=True) - def on_direction_change(event): - if hasattr(Direction, event["key"]): - maybe_new_direction = Direction[event["key"]].value - direction_vector_sum = tuple( - map(sum, zip(last_direction, maybe_new_direction)) - ) - if direction_vector_sum != (0, 0): - direction.current = maybe_new_direction - - grid_wrapper = reactpy.html.div({"on_key_down": on_direction_change}, grid) - - assign_grid_block_color(grid, food, "blue") - - for location in snake: - assign_grid_block_color(grid, location, "white") - - new_game_state = None - if snake[-1] in snake[:-1]: - assign_grid_block_color(grid, snake[-1], "red") - new_game_state = GameState.lost - elif len(snake) == grid_size**2: - assign_grid_block_color(grid, snake[-1], "yellow") - new_game_state = GameState.won - - interval = use_interval(0.5) - - @reactpy.hooks.use_effect - async def animate(): - if new_game_state is not None: - await asyncio.sleep(1) - set_game_state(new_game_state) - return - - await interval - - new_snake_head = ( - # grid wraps due to mod op here - (snake[-1][0] + direction.current[0]) % grid_size, - (snake[-1][1] + direction.current[1]) % grid_size, - ) - - if snake[-1] == food: - set_food() - new_snake = [*snake, new_snake_head] - else: - new_snake = snake[1:] + [new_snake_head] - - set_snake(new_snake) - - return grid_wrapper - - -def use_snake_food(grid_size, current_snake): - grid_points = {(x, y) for x in range(grid_size) for y in range(grid_size)} - points_not_in_snake = grid_points.difference(current_snake) - - food, _set_food = reactpy.hooks.use_state(current_snake[-1]) - - def set_food(): - _set_food(random.choice(list(points_not_in_snake))) - - return food, set_food - - -def use_interval(rate): - usage_time = reactpy.hooks.use_ref(time.time()) - - async def interval() -> None: - await asyncio.sleep(rate - (time.time() - usage_time.current)) - usage_time.current = time.time() - - return asyncio.ensure_future(interval()) - - -def create_grid(grid_size, block_scale): - return reactpy.html.div( - { - "style": { - "height": f"{block_scale * grid_size}px", - "width": f"{block_scale * grid_size}px", - "cursor": "pointer", - "display": "grid", - "grid-gap": 0, - "grid-template-columns": f"repeat({grid_size}, {block_scale}px)", - "grid-template-rows": f"repeat({grid_size}, {block_scale}px)", - }, - "tab_index": -1, - }, - [ - reactpy.html.div( - {"style": {"height": f"{block_scale}px"}, "key": i}, - [ - create_grid_block("black", block_scale, key=i) - for i in range(grid_size) - ], - ) - for i in range(grid_size) - ], - ) - - -def create_grid_block(color, block_scale, key): - return reactpy.html.div( - { - "style": { - "height": f"{block_scale}px", - "width": f"{block_scale}px", - "background_color": color, - "outline": "1px solid grey", - }, - "key": key, - } - ) - - -def assign_grid_block_color(grid, point, color): - x, y = point - block = grid["children"][x]["children"][y] - block["attributes"]["style"]["backgroundColor"] = color - - -reactpy.run(GameView) diff --git a/docs/source/reference/_examples/todo.py b/docs/source/reference/_examples/todo.py deleted file mode 100644 index 104ea59a9..000000000 --- a/docs/source/reference/_examples/todo.py +++ /dev/null @@ -1,35 +0,0 @@ -import reactpy - - -@reactpy.component -def Todo(): - items, set_items = reactpy.hooks.use_state([]) - - async def add_new_task(event): - if event["key"] == "Enter": - set_items([*items, event["target"]["value"]]) - - tasks = [] - - for index, text in enumerate(items): - - async def remove_task(event, index=index): - set_items(items[:index] + items[index + 1 :]) - - task_text = reactpy.html.td(reactpy.html.p(text)) - delete_button = reactpy.html.td( - {"on_click": remove_task}, reactpy.html.button(["x"]) - ) - tasks.append(reactpy.html.tr(task_text, delete_button)) - - task_input = reactpy.html.input({"on_key_down": add_new_task}) - task_table = reactpy.html.table(tasks) - - return reactpy.html.div( - reactpy.html.p("press enter to add a task:"), - task_input, - task_table, - ) - - -reactpy.run(Todo) diff --git a/docs/source/reference/_examples/use_reducer_counter.py b/docs/source/reference/_examples/use_reducer_counter.py deleted file mode 100644 index 6f9581dfd..000000000 --- a/docs/source/reference/_examples/use_reducer_counter.py +++ /dev/null @@ -1,27 +0,0 @@ -import reactpy - - -def reducer(count, action): - if action == "increment": - return count + 1 - elif action == "decrement": - return count - 1 - elif action == "reset": - return 0 - else: - msg = f"Unknown action '{action}'" - raise ValueError(msg) - - -@reactpy.component -def Counter(): - count, dispatch = reactpy.hooks.use_reducer(reducer, 0) - return reactpy.html.div( - f"Count: {count}", - reactpy.html.button({"on_click": lambda event: dispatch("reset")}, "Reset"), - reactpy.html.button({"on_click": lambda event: dispatch("increment")}, "+"), - reactpy.html.button({"on_click": lambda event: dispatch("decrement")}, "-"), - ) - - -reactpy.run(Counter) diff --git a/docs/source/reference/_examples/use_state_counter.py b/docs/source/reference/_examples/use_state_counter.py deleted file mode 100644 index b2d8c84a9..000000000 --- a/docs/source/reference/_examples/use_state_counter.py +++ /dev/null @@ -1,26 +0,0 @@ -import reactpy - - -def increment(last_count): - return last_count + 1 - - -def decrement(last_count): - return last_count - 1 - - -@reactpy.component -def Counter(): - initial_count = 0 - count, set_count = reactpy.hooks.use_state(initial_count) - return reactpy.html.div( - f"Count: {count}", - reactpy.html.button( - {"on_click": lambda event: set_count(initial_count)}, "Reset" - ), - reactpy.html.button({"on_click": lambda event: set_count(increment)}, "+"), - reactpy.html.button({"on_click": lambda event: set_count(decrement)}, "-"), - ) - - -reactpy.run(Counter) diff --git a/docs/source/reference/_examples/victory_chart.py b/docs/source/reference/_examples/victory_chart.py deleted file mode 100644 index ce37c522f..000000000 --- a/docs/source/reference/_examples/victory_chart.py +++ /dev/null @@ -1,7 +0,0 @@ -import reactpy - -victory = reactpy.web.module_from_template("react", "victory-bar", fallback="⌛") -VictoryBar = reactpy.web.export(victory, "VictoryBar") - -bar_style = {"parent": {"width": "500px"}, "data": {"fill": "royalblue"}} -reactpy.run(reactpy.component(lambda: VictoryBar({"style": bar_style}))) diff --git a/docs/source/reference/_static/vdom-json-schema.json b/docs/source/reference/_static/vdom-json-schema.json deleted file mode 100644 index b1005d2ed..000000000 --- a/docs/source/reference/_static/vdom-json-schema.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "$ref": "#/definitions/element", - "$schema": "http://json-schema.org/draft-07/schema", - "definitions": { - "element": { - "dependentSchemas": { - "error": { - "properties": { - "tagName": { - "maxLength": 0 - } - } - } - }, - "properties": { - "attributes": { - "type": "object" - }, - "children": { - "$ref": "#/definitions/elementChildren" - }, - "error": { - "type": "string" - }, - "eventHandlers": { - "$ref": "#/definitions/elementEventHandlers" - }, - "importSource": { - "$ref": "#/definitions/importSource" - }, - "key": { - "type": "string" - }, - "tagName": { - "type": "string" - } - }, - "required": ["tagName"], - "type": "object" - }, - "elementChildren": { - "items": { - "$ref": "#/definitions/elementOrString" - }, - "type": "array" - }, - "elementEventHandlers": { - "patternProperties": { - ".*": { - "$ref": "#/definitions/eventHander" - } - }, - "type": "object" - }, - "elementOrString": { - "if": { - "type": "object" - }, - "then": { - "$ref": "#/definitions/element" - }, - "type": ["object", "string"] - }, - "eventHandler": { - "properties": { - "preventDefault": { - "type": "boolean" - }, - "stopPropagation": { - "type": "boolean" - }, - "target": { - "type": "string" - } - }, - "required": ["target"], - "type": "object" - }, - "importSource": { - "properties": { - "fallback": { - "if": { - "not": { - "type": "null" - } - }, - "then": { - "$ref": "#/definitions/elementOrString" - }, - "type": ["object", "string", "null"] - }, - "source": { - "type": "string" - }, - "sourceType": { - "enum": ["URL", "NAME"] - }, - "unmountBeforeUpdate": { - "type": "boolean" - } - }, - "required": ["source"], - "type": "object" - } - } -} diff --git a/docs/source/reference/browser-events.rst b/docs/source/reference/browser-events.rst deleted file mode 100644 index 632be410a..000000000 --- a/docs/source/reference/browser-events.rst +++ /dev/null @@ -1,65 +0,0 @@ -.. _Browser Events: - -Browser Events 🚧 -================= - -The event types below are triggered by an event in the bubbling phase. To register an -event handler for the capture phase, append Capture to the event name; for example, -instead of using ``onClick``, you would use ``onClickCapture`` to handle the click event -in the capture phase. - -.. note:: - - Under construction 🚧 - - -Clipboard Events ----------------- - -Composition Events ------------------- - -Keyboard Events ---------------- - -Focus Events ------------- - -Form Events ------------ - -Generic Events --------------- - -Mouse Events ------------- - -Pointer Events --------------- - -Selection Events ----------------- - -Touch Events ------------- - -UI Events ---------- - -Wheel Events ------------- - -Media Events ------------- - -Image Events ------------- - -Animation Events ----------------- - -Transition Events ------------------ - -Other Events ------------- diff --git a/docs/source/reference/hooks-api.rst b/docs/source/reference/hooks-api.rst deleted file mode 100644 index ca8123e85..000000000 --- a/docs/source/reference/hooks-api.rst +++ /dev/null @@ -1,379 +0,0 @@ -========= -Hooks API -========= - -Hooks are functions that allow you to "hook into" the life cycle events and state of -Components. Their usage should always follow the :ref:`Rules of Hooks`. For most use -cases the :ref:`Basic Hooks` should be enough, however the remaining -:ref:`Supplementary Hooks` should fulfill less common scenarios. - - -Basic Hooks -=========== - - -Use State ---------- - -.. code-block:: - - state, set_state = use_state(initial_state) - -Returns a stateful value and a function to update it. - -During the first render the ``state`` will be identical to the ``initial_state`` passed -as the first argument. However in subsequent renders ``state`` will take on the value -passed to ``set_state``. - -.. code-block:: - - set_state(new_state) - -The ``set_state`` function accepts a ``new_state`` as its only argument and schedules a -re-render of the component where ``use_state`` was initially called. During these -subsequent re-renders the ``state`` returned by ``use_state`` will take on the value -of ``new_state``. - -.. note:: - - The identity of ``set_state`` is guaranteed to be preserved across renders. This - means it can safely be omitted from dependency lists in :ref:`Use Effect` or - :ref:`Use Callback`. - - -Functional Updates -.................. - -If the new state is computed from the previous state, you can pass a function which -accepts a single argument (the previous state) and returns the next state. Consider this -simply use case of a counter where we've pulled out logic for increment and -decremented the count: - -.. reactpy:: _examples/use_state_counter - -We use the functional form for the "+" and "-" buttons since the next ``count`` depends -on the previous value, while for the "Reset" button we simple assign the -``initial_count`` since it is independent of the prior ``count``. This is a trivial -example, but it demonstrates how complex state logic can be factored out into well -defined and potentially reusable functions. - - -Lazy Initial State -.................. - -In cases where it is costly to create the initial value for ``use_state``, you can pass -a constructor function that accepts no arguments instead - it will be called on the -first render of a component, but will be disregarded in all following renders: - -.. code-block:: - - state, set_state = use_state(lambda: some_expensive_computation(a, b, c)) - - -Skipping Updates -................ - -If you update a State Hook to the same value as the current state then the component which -owns that state will not be rendered again. We check ``if new_state is current_state`` -in order to determine whether there has been a change. Thus the following would not -result in a re-render: - -.. code-block:: - - state, set_state = use_state([]) - set_state(state) - - -Use Effect ----------- - -.. code-block:: - - use_effect(did_render) - -The ``use_effect`` hook accepts a function which may be imperative, or mutate state. The -function will be called immediately after the layout has fully updated. - -Asynchronous actions, mutations, subscriptions, and other `side effects`_ can cause -unexpected bugs if placed in the main body of a component's render function. Thus the -``use_effect`` hook provides a way to safely escape the purely functional world of -component render functions. - -.. note:: - - Normally in React the ``did_render`` function is called once an update has been - committed to the screen. Since no such action is performed by ReactPy, and the time - at which the update is displayed cannot be known we are unable to achieve parity - with this behavior. - - -Cleaning Up Effects -................... - -If the effect you wish to enact creates resources, you'll probably need to clean them -up. In such cases you may simply return a function that addresses this from the -``did_render`` function which created the resource. Consider the case of opening and -then closing a connection: - -.. code-block:: - - def establish_connection(): - connection = open_connection() - return lambda: close_connection(connection) - - use_effect(establish_connection) - -The clean-up function will be run before the component is unmounted or, before the next -effect is triggered when the component re-renders. You can -:ref:`conditionally fire events ` to avoid triggering them each -time a component renders. - - -Conditional Effects -................... - -By default, effects are triggered after every successful render to ensure that all state -referenced by the effect is up to date. However, when an effect function references -non-global variables, the effect will only if the value of that variable changes. For -example, imagine that we had an effect that connected to a ``url`` state variable: - -.. code-block:: - - url, set_url = use_state("https://example.com") - - def establish_connection(): - connection = open_connection(url) - return lambda: close_connection(connection) - - use_effect(establish_connection) - -Here, a new connection will be established whenever a new ``url`` is set. - - -Async Effects -............. - -A behavior unique to ReactPy's implementation of ``use_effect`` is that it natively -supports ``async`` functions: - -.. code-block:: - - async def non_blocking_effect(): - resource = await do_something_asynchronously() - return lambda: blocking_close(resource) - - use_effect(non_blocking_effect) - - -There are **three important subtleties** to note about using asynchronous effects: - -1. The cleanup function must be a normal synchronous function. - -2. Asynchronous effects which do not complete before the next effect is created - following a re-render will be cancelled. This means an - :class:`~asyncio.CancelledError` will be raised somewhere in the body of the effect. - -3. An asynchronous effect may occur any time after the update which added this effect - and before the next effect following a subsequent update. - - -Manual Effect Conditions -........................ - -In some cases, you may want to explicitly declare when an effect should be triggered. -You can do this by passing ``dependencies`` to ``use_effect``. Each of the following -values produce different effect behaviors: - -- ``use_effect(..., dependencies=None)`` - triggers and cleans up on every render. -- ``use_effect(..., dependencies=[])`` - only triggers on the first and cleans up after - the last render. -- ``use_effect(..., dependencies=[x, y])`` - triggers on the first render and on subsequent renders if - ``x`` or ``y`` have changed. - - -Use Context ------------ - -.. code-block:: - - value = use_context(MyContext) - -Accepts a context object (the value returned from -:func:`reactpy.core.hooks.create_context`) and returns the current context value for that -context. The current context value is determined by the ``value`` argument passed to the -nearest ``MyContext`` in the tree. - -When the nearest above the component updates, this Hook will -trigger a rerender with the latest context value passed to that MyContext provider. Even -if an ancestor uses React.memo or shouldComponentUpdate, a rerender will still happen -starting at the component itself using useContext. - - -Supplementary Hooks -=================== - - -Use Reducer ------------ - -.. code-block:: - - state, dispatch_action = use_reducer(reducer, initial_state) - -An alternative and derivative of :ref:`Use State` the ``use_reducer`` hook, instead of -directly assigning a new state, allows you to specify an action which will transition -the previous state into the next state. This transition is defined by a reducer function -of the form ``(current_state, action) -> new_state``. The ``use_reducer`` hook then -returns the current state and a ``dispatch_action`` function that accepts an ``action`` -and causes a transition to the next state via the ``reducer``. - -``use_reducer`` is generally preferred to ``use_state`` if logic for transitioning from -one state to the next is especially complex or involves nested data structures. -``use_reducer`` can also be used to collect several ``use_state`` calls together - this -may be slightly more performant as well as being preferable since there is only one -``dispatch_action`` callback versus the many ``set_state`` callbacks. - -We can rework the :ref:`Functional Updates` counter example to use ``use_reducer``: - -.. reactpy:: _examples/use_reducer_counter - -.. note:: - - The identity of the ``dispatch_action`` function is guaranteed to be preserved - across re-renders throughout the lifetime of the component. This means it can safely - be omitted from dependency lists in :ref:`Use Effect` or :ref:`Use Callback`. - - -Use Callback ------------- - -.. code-block:: - - memoized_callback = use_callback(lambda: do_something(a, b)) - -A derivative of :ref:`Use Memo`, the ``use_callback`` hook returns a -`memoized `_ callback. This is useful when passing callbacks to child -components which check reference equality to prevent unnecessary renders. The -``memoized_callback`` will only change when any local variables is references do. - -.. note:: - - You may manually specify what values the callback depends on in the :ref:`same way - as effects ` using the ``dependencies`` parameter. - - -Use Memo --------- - -.. code-block:: - - memoized_value = use_memo(lambda: compute_something_expensive(a, b)) - -Returns a `memoized `_ value. By passing a constructor function accepting -no arguments and an array of dependencies for that constructor, the ``use_callback`` -hook will return the value computed by the constructor. The ``memoized_value`` will only -be recomputed if a local variable referenced by the constructor changes (e.g. ``a`` or -``b`` here). This optimizes performance because you don't need to -``compute_something_expensive`` on every render. - -Unlike ``use_effect`` the constructor function is called during each render (instead of -after) and should not incur side effects. - -.. warning:: - - Remember that you shouldn't optimize something unless you know it's a performance - bottleneck. Write your code without ``use_memo`` first and then add it to targeted - sections that need a speed-up. - -.. note:: - - You may manually specify what values the callback depends on in the :ref:`same way - as effects ` using the ``dependencies`` parameter. - - -Use Ref -------- - -.. code-block:: - - ref_container = use_ref(initial_value) - -Returns a mutable :class:`~reactpy.utils.Ref` object that has a single -:attr:`~reactpy.utils.Ref.current` attribute that at first contains the ``initial_state``. -The identity of the ``Ref`` object will be preserved for the lifetime of the component. - -A ``Ref`` is most useful if you need to incur side effects since updating its -``.current`` attribute doesn't trigger a re-render of the component. You'll often use this -hook alongside :ref:`Use Effect` or in response to component event handlers. - - -.. links -.. ===== - -.. _React Hooks: https://reactjs.org/docs/hooks-reference.html -.. _side effects: https://en.wikipedia.org/wiki/Side_effect_(computer_science) -.. _memoization: https://en.wikipedia.org/wiki/Memoization - - -Rules of Hooks -============== - -Hooks are just normal Python functions, but there's a bit of magic to them, and in order -for that magic to work you've got to follow two rules. Thankfully we supply a -:ref:`Flake8 Plugin` to help enforce them. - - -Only call outside flow controls -------------------------------- - -**Don't call hooks inside loops, conditions, or nested functions.** Instead you must -always call hooks at the top level of your functions. By adhering to this rule you -ensure that hooks are always called in the exact same order. This fact is what allows -ReactPy to preserve the state of hooks between multiple calls to ``useState`` and -``useEffect`` calls. - - -Only call in render functions ------------------------------ - -**Don't call hooks from regular Python functions.** Instead you should: - -- ✅ Call Hooks from a component's render function. - -- ✅ Call Hooks from another custom hook - -Following this rule ensures stateful logic for ReactPy component is always clearly -separated from the rest of your codebase. - - -Flake8 Plugin -------------- - -We provide a Flake8 plugin called `flake8-reactpy-hooks `_ that helps -to enforce the two rules described above. You can ``pip`` install it directly, or with -the ``lint`` extra for ReactPy: - -.. code-block:: bash - - pip install flake8-reactpy-hooks - -Once installed running, ``flake8`` on your code will start catching errors. For example: - -.. code-block:: bash - - flake8 my_reactpy_components.py - -Might produce something like the following output: - -.. code-block:: text - - ./my_reactpy_components:10:8 ROH102 hook 'use_effect' used inside if statement - ./my_reactpy_components:23:4 ROH102 hook 'use_state' used outside component or hook definition - -See the Flake8 docs for -`more info `__. - -.. links -.. ===== - -.. _Flake8 Linter Plugin: https://github.com/reactive-python/flake8-reactpy-hooks diff --git a/docs/source/reference/html-attributes.rst b/docs/source/reference/html-attributes.rst deleted file mode 100644 index 91813c355..000000000 --- a/docs/source/reference/html-attributes.rst +++ /dev/null @@ -1,197 +0,0 @@ -.. testcode:: - - from reactpy import html - - -HTML Attributes -=============== - -In ReactPy, HTML attributes are specified using snake_case instead of dash-separated -words. For example, ``tabindex`` and ``margin-left`` become ``tab_index`` and -``margin_left`` respectively. - - -Notable Attributes -------------------- - -Some attributes in ReactPy are renamed, have special meaning, or are used differently -than in HTML. - -``style`` -......... - -As mentioned above, instead of using a string to specify the ``style`` attribute, we use -a dictionary to describe the CSS properties we want to apply to an element. For example, -the following HTML: - -.. code-block:: html - -
-

My Todo List

-
    -
  • Build a cool new app
  • -
  • Share it with the world!
  • -
-
- -Would be written in ReactPy as: - -.. testcode:: - - html.div( - { - "style": { - "width": "50%", - "margin_left": "25%", - }, - }, - html.h1( - { - "style": { - "margin_top": "0px", - }, - }, - "My Todo List", - ), - html.ul( - html.li("Build a cool new app"), - html.li("Share it with the world!"), - ), - ) - -``class`` vs ``class_name`` -........................... - -In HTML, the ``class`` attribute is used to specify a CSS class for an element. In -ReactPy, this attribute is renamed to ``class_name`` to avoid conflicting with the -``class`` keyword in Python. For example, the following HTML: - -.. code-block:: html - -
-

My Todo List

-
    -
  • Build a cool new app
  • -
  • Share it with the world!
  • -
-
- -Would be written in ReactPy as: - -.. testcode:: - - html.div( - {"class_name": "container"}, - html.h1({"class_name": "title"}, "My Todo List"), - html.ul( - {"class_name": "list"}, - html.li({"class_name": "item"}, "Build a cool new app"), - html.li({"class_name": "item"}, "Share it with the world!"), - ), - ) - -``for`` vs ``html_for`` -....................... - -In HTML, the ``for`` attribute is used to specify the ``id`` of the element it's -associated with. In ReactPy, this attribute is renamed to ``html_for`` to avoid -conflicting with the ``for`` keyword in Python. For example, the following HTML: - -.. code-block:: html - -
- - -
- -Would be written in ReactPy as: - -.. testcode:: - - html.div( - html.label({"html_for": "todo"}, "Todo:"), - html.input({"id": "todo", "type": "text"}), - ) - -``dangerously_set_inner_HTML`` -.............................. - -This is used to set the ``innerHTML`` property of an element and should be provided a -dictionary with a single key ``__html`` whose value is the HTML to be set. It should be -used with **extreme caution** as it can lead to XSS attacks if the HTML inside isn't -trusted (for example if it comes from user input). - - -All Attributes --------------- - -`access_key `__ - A string. Specifies a keyboard shortcut for the element. Not generally recommended. - -`aria_* `__ - ARIA attributes let you specify the accessibility tree information for this element. - See ARIA attributes for a complete reference. In ReactPy, all ARIA attribute names are - exactly the same as in HTML. - -`auto_capitalize `__ - A string. Specifies whether and how the user input should be capitalized. - -`content_editable `__ - A boolean. If true, the browser lets the user edit the rendered element directly. This - is used to implement rich text input libraries like Lexical. ReactPy warns if you try - to pass children to an element with ``content_editable = True`` because ReactPy will - not be able to update its content after user edits. - -`data_* `__ - Data attributes let you attach some string data to the element, for example - data-fruit="banana". In ReactPy, they are not commonly used because you would usually - read data from props or state instead. - -`dir `__ - Either ``"ltr"`` or ``"rtl"``. Specifies the text direction of the element. - -`draggable `__ - A boolean. Specifies whether the element is draggable. Part of HTML Drag and Drop API. - -`enter_key_hint `__ - A string. Specifies which action to present for the enter key on virtual keyboards. - -`hidden