├── tests ├── __init__.py └── test_ibkr.py ├── .python-version ├── FUNDING.yml ├── tws.jpg ├── .gitignore ├── ibgateway.jpg ├── renovate.json ├── start-docker.sh ├── image-files ├── index.html ├── replace.sh └── start.sh ├── latest ├── image-files │ ├── index.html │ ├── replace.sh │ └── start.sh └── Dockerfile ├── stable ├── image-files │ ├── index.html │ ├── replace.sh │ └── start.sh └── Dockerfile ├── pyproject.toml ├── .github └── workflows │ ├── start-detect-releases.yml │ ├── docker.yml │ └── detect-releases.yml ├── Dockerfile.template ├── README.md └── uv.lock /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.14 -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [extrange] -------------------------------------------------------------------------------- /tws.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrange/ibkr-docker/HEAD/tws.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | compose.yml 3 | .pdm-python 4 | .venv 5 | *.pyc 6 | __pycache__ -------------------------------------------------------------------------------- /ibgateway.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/extrange/ibkr-docker/HEAD/ibgateway.jpg -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["extrange/renovate-config:exceptMajor"] 4 | } 5 | -------------------------------------------------------------------------------- /start-docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker run \ 4 | -p '6089:6080' \ 5 | -p '8888:8888' \ 6 | --ulimit nofile=10000 \ 7 | -e USERNAME \ 8 | -e PASSWORD \ 9 | -e GATEWAY_OR_TWS=gateway \ 10 | -e IBC_TradingMode=paper \ 11 | -e IBC_AcceptNonBrokerageAccountWarning=yes \ 12 | -e IBC_AcceptIncomingConnectionAction=accept \ 13 | -d \ 14 | image -------------------------------------------------------------------------------- /image-files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TWS Docker 5 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /latest/image-files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TWS Docker 5 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /stable/image-files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TWS Docker 5 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/test_ibkr.py: -------------------------------------------------------------------------------- 1 | from ib_insync import IB 2 | import pytest 3 | 4 | @pytest.mark.asyncio 5 | async def test_ib_connection(): 6 | attempts = 0 7 | ib = IB() 8 | while not ib.isConnected(): 9 | if attempts >= 3: 10 | raise Exception("Failed to connect to IBKR after 3 attempts") 11 | try: 12 | await ib.connectAsync('localhost', 8888, clientId=0 ) 13 | except Exception: 14 | pass 15 | attempts += 1 16 | 17 | ib.disconnect() 18 | 19 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "ibkr-docker" 3 | version = "0.1.0" 4 | description = "IBKR in Docker" 5 | authors = [ 6 | { name = "extrange", email = "29305375+extrange@users.noreply.github.com" }, 7 | ] 8 | dependencies = ["ib-insync>=0.9.86"] 9 | requires-python = ">=3.12" 10 | readme = "README.md" 11 | license = { text = "MIT" } 12 | 13 | [tool.uv] 14 | dev-dependencies = [ 15 | "ipykernel>=6.29.5", 16 | "pyright[nodejs]>=1.1.382.post0", 17 | "ruff>=0.6.8", 18 | "pytest>=8.3.3", 19 | ] 20 | -------------------------------------------------------------------------------- /.github/workflows/start-detect-releases.yml: -------------------------------------------------------------------------------- 1 | name: Start detect-releases.yml 2 | # Required because making a matrix element conditional is difficult 3 | # https://stackoverflow.com/questions/65384420/how-do-i-make-a-github-action-matrix-element-conditional 4 | 5 | on: 6 | schedule: 7 | - cron: "0 8 * * *" # 8AM UTC daily 8 | 9 | workflow_dispatch: 10 | 11 | jobs: 12 | stable: 13 | name: Check stable release 14 | uses: ./.github/workflows/detect-releases.yml 15 | with: 16 | channel: stable 17 | 18 | latest: 19 | name: Check latest release 20 | uses: ./.github/workflows/detect-releases.yml 21 | with: 22 | channel: latest 23 | -------------------------------------------------------------------------------- /image-files/replace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Overrides a specified ini file with IBC_ environment variables 4 | # Note: Will NOT work if backslashes '\' are present 5 | # Case-sensitive 6 | 7 | # Fail fast 8 | set -Eeuo pipefail 9 | 10 | if [ $# -ne 1 ]; then 11 | echo "Usage: ./replace.sh " 12 | exit 1 13 | fi 14 | 15 | target=$1 16 | 17 | # Only select environment variables with IBC_ prefix, 18 | # then trim that prefix out 19 | prefix="IBC_" 20 | env_vars=$(printenv | grep -E "^${prefix}.*" | cut -c $((${#prefix} + 1))-) 21 | 22 | printf "Set variables:\n%s\n" "${env_vars}" 23 | 24 | # Generate sed script file from override 25 | script=$(sed -r 's/^((\w+=).*$)/\/^\2.*$\/c\\\1/' <<<"$env_vars") 26 | 27 | # Replace in-place, making a backup 28 | sed --in-place=.bak -r "$script" "$target" 29 | 30 | printf "Changes made to %s:\n" "$target" 31 | printf "%s\n" "$(diff "$target.bak" "$target")" 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /latest/image-files/replace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Overrides a specified ini file with IBC_ environment variables 4 | # Note: Will NOT work if backslashes '\' are present 5 | # Case-sensitive 6 | 7 | # Fail fast 8 | set -Eeuo pipefail 9 | 10 | if [ $# -ne 1 ]; then 11 | echo "Usage: ./replace.sh " 12 | exit 1 13 | fi 14 | 15 | target=$1 16 | 17 | # Only select environment variables with IBC_ prefix, 18 | # then trim that prefix out 19 | prefix="IBC_" 20 | env_vars=$(printenv | grep -E "^${prefix}.*" | cut -c $((${#prefix} + 1))-) 21 | 22 | printf "Set variables:\n%s\n" "${env_vars}" 23 | 24 | # Generate sed script file from override 25 | script=$(sed -r 's/^((\w+=).*$)/\/^\2.*$\/c\\\1/' <<<"$env_vars") 26 | 27 | # Replace in-place, making a backup 28 | sed --in-place=.bak -r "$script" "$target" 29 | 30 | printf "Changes made to %s:\n" "$target" 31 | printf "%s\n" "$(diff "$target.bak" "$target")" 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /stable/image-files/replace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Overrides a specified ini file with IBC_ environment variables 4 | # Note: Will NOT work if backslashes '\' are present 5 | # Case-sensitive 6 | 7 | # Fail fast 8 | set -Eeuo pipefail 9 | 10 | if [ $# -ne 1 ]; then 11 | echo "Usage: ./replace.sh " 12 | exit 1 13 | fi 14 | 15 | target=$1 16 | 17 | # Only select environment variables with IBC_ prefix, 18 | # then trim that prefix out 19 | prefix="IBC_" 20 | env_vars=$(printenv | grep -E "^${prefix}.*" | cut -c $((${#prefix} + 1))-) 21 | 22 | printf "Set variables:\n%s\n" "${env_vars}" 23 | 24 | # Generate sed script file from override 25 | script=$(sed -r 's/^((\w+=).*$)/\/^\2.*$\/c\\\1/' <<<"$env_vars") 26 | 27 | # Replace in-place, making a backup 28 | sed --in-place=.bak -r "$script" "$target" 29 | 30 | printf "Changes made to %s:\n" "$target" 31 | printf "%s\n" "$(diff "$target.bak" "$target")" 32 | 33 | exit 0 34 | -------------------------------------------------------------------------------- /latest/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:13@sha256:fd8f5a1df07b5195613e4b9a0b6a947d3772a151b81975db27d47f093f60c6e6 AS setup 2 | 3 | ENV IBC_VERSION=3.22.0 4 | 5 | RUN apt-get update && \ 6 | apt-get install --no-install-recommends -y \ 7 | ca-certificates git libxtst6 libgtk-3-0 openbox procps python3 socat tigervnc-standalone-server unzip wget2 xterm \ 8 | # https://github.com/extrange/ibkr-docker/issues/74 9 | libasound2 \ 10 | libnss3 \ 11 | libgbm1 \ 12 | libnspr4 13 | 14 | # Setup noVNC for browser VNC access 15 | RUN git clone --depth 1 https://github.com/novnc/noVNC.git && \ 16 | chmod +x ./noVNC/utils/novnc_proxy && \ 17 | git clone --depth 1 https://github.com/novnc/websockify.git /noVNC/utils/websockify 18 | 19 | # Override default noVNC file listing 20 | COPY image-files/index.html /noVNC 21 | 22 | # Download and setup IBC 23 | RUN wget2 https://github.com/IbcAlpha/IBC/releases/download/${IBC_VERSION}/IBCLinux-${IBC_VERSION}.zip -O ibc.zip \ 24 | && unzip ibc.zip -d /opt/ibc \ 25 | && rm ibc.zip 26 | 27 | ENV INSTALL_FILENAME="ibgateway-10.42.1a-standalone-linux-x64.sh" 28 | 29 | # Fetch hashes 30 | RUN wget2 "https://github.com/extrange/ibkr-docker/releases/download/10.42.1a-latest/ibgateway-10.42.1a-standalone-linux-x64.sh.sha256" \ 31 | -O hash 32 | 33 | # Download IB Gateway (which contains TWS) and check hashes 34 | RUN wget2 "https://github.com/extrange/ibkr-docker/releases/download/10.42.1a-latest/ibgateway-10.42.1a-standalone-linux-x64.sh" \ 35 | -O "$INSTALL_FILENAME" \ 36 | && sha256sum -c hash \ 37 | && chmod +x "$INSTALL_FILENAME" \ 38 | && yes '' | "./$INSTALL_FILENAME" \ 39 | && rm "$INSTALL_FILENAME" 40 | 41 | # Copy scripts 42 | COPY image-files/start.sh image-files/replace.sh / 43 | 44 | RUN mkdir -p ~/ibc && mv /opt/ibc/config.ini ~/ibc/config.ini 45 | 46 | RUN chmod a+x ./*.sh /opt/ibc/*.sh /opt/ibc/scripts/*.sh 47 | 48 | CMD [ "/start.sh" ] -------------------------------------------------------------------------------- /stable/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:13@sha256:fd8f5a1df07b5195613e4b9a0b6a947d3772a151b81975db27d47f093f60c6e6 AS setup 2 | 3 | ENV IBC_VERSION=3.22.0 4 | 5 | RUN apt-get update && \ 6 | apt-get install --no-install-recommends -y \ 7 | ca-certificates git libxtst6 libgtk-3-0 openbox procps python3 socat tigervnc-standalone-server unzip wget2 xterm \ 8 | # https://github.com/extrange/ibkr-docker/issues/74 9 | libasound2 \ 10 | libnss3 \ 11 | libgbm1 \ 12 | libnspr4 13 | 14 | # Setup noVNC for browser VNC access 15 | RUN git clone --depth 1 https://github.com/novnc/noVNC.git && \ 16 | chmod +x ./noVNC/utils/novnc_proxy && \ 17 | git clone --depth 1 https://github.com/novnc/websockify.git /noVNC/utils/websockify 18 | 19 | # Override default noVNC file listing 20 | COPY image-files/index.html /noVNC 21 | 22 | # Download and setup IBC 23 | RUN wget2 https://github.com/IbcAlpha/IBC/releases/download/${IBC_VERSION}/IBCLinux-${IBC_VERSION}.zip -O ibc.zip \ 24 | && unzip ibc.zip -d /opt/ibc \ 25 | && rm ibc.zip 26 | 27 | ENV INSTALL_FILENAME="ibgateway-10.37.1n-standalone-linux-x64.sh" 28 | 29 | # Fetch hashes 30 | RUN wget2 "https://github.com/extrange/ibkr-docker/releases/download/10.37.1n-stable/ibgateway-10.37.1n-standalone-linux-x64.sh.sha256" \ 31 | -O hash 32 | 33 | # Download IB Gateway (which contains TWS) and check hashes 34 | RUN wget2 "https://github.com/extrange/ibkr-docker/releases/download/10.37.1n-stable/ibgateway-10.37.1n-standalone-linux-x64.sh" \ 35 | -O "$INSTALL_FILENAME" \ 36 | && sha256sum -c hash \ 37 | && chmod +x "$INSTALL_FILENAME" \ 38 | && yes '' | "./$INSTALL_FILENAME" \ 39 | && rm "$INSTALL_FILENAME" 40 | 41 | # Copy scripts 42 | COPY image-files/start.sh image-files/replace.sh / 43 | 44 | RUN mkdir -p ~/ibc && mv /opt/ibc/config.ini ~/ibc/config.ini 45 | 46 | RUN chmod a+x ./*.sh /opt/ibc/*.sh /opt/ibc/scripts/*.sh 47 | 48 | CMD [ "/start.sh" ] -------------------------------------------------------------------------------- /Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM debian:13@sha256:fd8f5a1df07b5195613e4b9a0b6a947d3772a151b81975db27d47f093f60c6e6 AS setup 2 | 3 | ENV IBC_VERSION=3.22.0 4 | 5 | RUN apt-get update && \ 6 | apt-get install --no-install-recommends -y \ 7 | ca-certificates git libxtst6 libgtk-3-0 openbox procps python3 socat tigervnc-standalone-server unzip wget2 xterm \ 8 | # https://github.com/extrange/ibkr-docker/issues/74 9 | libasound2 \ 10 | libnss3 \ 11 | libgbm1 \ 12 | libnspr4 13 | 14 | # Setup noVNC for browser VNC access 15 | RUN git clone --depth 1 https://github.com/novnc/noVNC.git && \ 16 | chmod +x ./noVNC/utils/novnc_proxy && \ 17 | git clone --depth 1 https://github.com/novnc/websockify.git /noVNC/utils/websockify 18 | 19 | # Override default noVNC file listing 20 | COPY image-files/index.html /noVNC 21 | 22 | # Download and setup IBC 23 | RUN wget2 https://github.com/IbcAlpha/IBC/releases/download/${IBC_VERSION}/IBCLinux-${IBC_VERSION}.zip -O ibc.zip \ 24 | && unzip ibc.zip -d /opt/ibc \ 25 | && rm ibc.zip 26 | 27 | ENV INSTALL_FILENAME="ibgateway-${VERSION}-standalone-linux-x64.sh" 28 | 29 | # Fetch hashes 30 | RUN wget2 "https://github.com/extrange/ibkr-docker/releases/download/${VERSION}-${CHANNEL}/ibgateway-${VERSION}-standalone-linux-x64.sh.sha256" \ 31 | -O hash 32 | 33 | # Download IB Gateway (which contains TWS) and check hashes 34 | RUN wget2 "https://github.com/extrange/ibkr-docker/releases/download/${VERSION}-${CHANNEL}/ibgateway-${VERSION}-standalone-linux-x64.sh" \ 35 | -O "$INSTALL_FILENAME" \ 36 | && sha256sum -c hash \ 37 | && chmod +x "$INSTALL_FILENAME" \ 38 | && yes '' | "./$INSTALL_FILENAME" \ 39 | && rm "$INSTALL_FILENAME" 40 | 41 | # Copy scripts 42 | COPY image-files/start.sh image-files/replace.sh / 43 | 44 | RUN mkdir -p ~/ibc && mv /opt/ibc/config.ini ~/ibc/config.ini 45 | 46 | RUN chmod a+x ./*.sh /opt/ibc/*.sh /opt/ibc/scripts/*.sh 47 | 48 | CMD [ "/start.sh" ] -------------------------------------------------------------------------------- /image-files/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Fail fast 4 | set -Eeuo pipefail 5 | 6 | export DISPLAY=:0 7 | 8 | # Clear previous lockfile 9 | rm -f /tmp/.X0-lock 10 | 11 | # Start VNC server 12 | Xvnc -SecurityTypes None -AlwaysShared=1 -geometry 1920x1080 :0 & 13 | 14 | # Start noVNC server 15 | ./noVNC/utils/novnc_proxy --vnc localhost:5900 & 16 | 17 | # Start openbox 18 | openbox & 19 | 20 | # Start either TWS or IB Gateway 21 | if [[ -z ${GATEWAY_OR_TWS:-} ]]; then 22 | # Start TWS by default if not specified 23 | GATEWAY_OR_TWS=tws 24 | command= 25 | elif [[ ${GATEWAY_OR_TWS@L} = "gateway" ]]; then 26 | command='-g' 27 | elif [[ ${GATEWAY_OR_TWS@L} = "tws" ]]; then 28 | command= 29 | else 30 | printf "GATEWAY_OR_TWS must be either 'gateway' or 'tws': got '%s'\n" "$GATEWAY_OR_TWS" 31 | exit 1 32 | fi 33 | 34 | # Forward correct port with socat 35 | if [[ ${GATEWAY_OR_TWS@L} = "gateway" ]]; then 36 | if [[ ${IBC_TradingMode:-live} = "live" ]]; then 37 | # IBGateway Live 38 | port=4001 39 | else 40 | # IBGateway Paper 41 | port=4002 42 | fi 43 | elif [[ ${IBC_TradingMode:-live} = "live" ]]; then 44 | # TWS Live 45 | port=7496 46 | else 47 | # TWS Paper 48 | port=7497 49 | fi 50 | 51 | printf "Listening for incoming API connections on %s\n" $port 52 | socat -d -d TCP-LISTEN:8888,fork TCP:127.0.0.1:${port} & 53 | 54 | # Hacky way to get the major version for IB Gateway/TWS 55 | TWS_MAJOR_VERSION=$(ls ~/Jts/ibgateway/.) 56 | 57 | # Override /opt/ibc/config.ini with environment variables 58 | ./replace.sh ~/ibc/config.ini 59 | 60 | # --on2fatimeout was previously supplied by gatewaystart.sh/twsstart.sh, 61 | # so we need to supply it here. The rest of the arguments can be read from 62 | # the config.ini file. 63 | 64 | exec /opt/ibc/scripts/ibcstart.sh "${TWS_MAJOR_VERSION}" $command \ 65 | "--user=${USERNAME:-}" \ 66 | "--pw=${PASSWORD:-}" \ 67 | "--on2fatimeout=${TWOFA_TIMEOUT_ACTION:-restart}" \ 68 | "--tws-settings-path=${TWS_SETTINGS_PATH:-}" 69 | -------------------------------------------------------------------------------- /latest/image-files/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Fail fast 4 | set -Eeuo pipefail 5 | 6 | export DISPLAY=:0 7 | 8 | # Clear previous lockfile 9 | rm -f /tmp/.X0-lock 10 | 11 | # Start VNC server 12 | Xvnc -SecurityTypes None -AlwaysShared=1 -geometry 1920x1080 :0 & 13 | 14 | # Start noVNC server 15 | ./noVNC/utils/novnc_proxy --vnc localhost:5900 & 16 | 17 | # Start openbox 18 | openbox & 19 | 20 | # Start either TWS or IB Gateway 21 | if [[ -z ${GATEWAY_OR_TWS:-} ]]; then 22 | # Start TWS by default if not specified 23 | GATEWAY_OR_TWS=tws 24 | command= 25 | elif [[ ${GATEWAY_OR_TWS@L} = "gateway" ]]; then 26 | command='-g' 27 | elif [[ ${GATEWAY_OR_TWS@L} = "tws" ]]; then 28 | command= 29 | else 30 | printf "GATEWAY_OR_TWS must be either 'gateway' or 'tws': got '%s'\n" "$GATEWAY_OR_TWS" 31 | exit 1 32 | fi 33 | 34 | # Forward correct port with socat 35 | if [[ ${GATEWAY_OR_TWS@L} = "gateway" ]]; then 36 | if [[ ${IBC_TradingMode:-live} = "live" ]]; then 37 | # IBGateway Live 38 | port=4001 39 | else 40 | # IBGateway Paper 41 | port=4002 42 | fi 43 | elif [[ ${IBC_TradingMode:-live} = "live" ]]; then 44 | # TWS Live 45 | port=7496 46 | else 47 | # TWS Paper 48 | port=7497 49 | fi 50 | 51 | printf "Listening for incoming API connections on %s\n" $port 52 | socat -d -d TCP-LISTEN:8888,fork TCP:127.0.0.1:${port} & 53 | 54 | # Hacky way to get the major version for IB Gateway/TWS 55 | TWS_MAJOR_VERSION=$(ls ~/Jts/ibgateway/.) 56 | 57 | # Override /opt/ibc/config.ini with environment variables 58 | ./replace.sh ~/ibc/config.ini 59 | 60 | # --on2fatimeout was previously supplied by gatewaystart.sh/twsstart.sh, 61 | # so we need to supply it here. The rest of the arguments can be read from 62 | # the config.ini file. 63 | 64 | exec /opt/ibc/scripts/ibcstart.sh "${TWS_MAJOR_VERSION}" $command \ 65 | "--user=${USERNAME:-}" \ 66 | "--pw=${PASSWORD:-}" \ 67 | "--on2fatimeout=${TWOFA_TIMEOUT_ACTION:-restart}" \ 68 | "--tws-settings-path=${TWS_SETTINGS_PATH:-}" 69 | -------------------------------------------------------------------------------- /stable/image-files/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Fail fast 4 | set -Eeuo pipefail 5 | 6 | export DISPLAY=:0 7 | 8 | # Clear previous lockfile 9 | rm -f /tmp/.X0-lock 10 | 11 | # Start VNC server 12 | Xvnc -SecurityTypes None -AlwaysShared=1 -geometry 1920x1080 :0 & 13 | 14 | # Start noVNC server 15 | ./noVNC/utils/novnc_proxy --vnc localhost:5900 & 16 | 17 | # Start openbox 18 | openbox & 19 | 20 | # Start either TWS or IB Gateway 21 | if [[ -z ${GATEWAY_OR_TWS:-} ]]; then 22 | # Start TWS by default if not specified 23 | GATEWAY_OR_TWS=tws 24 | command= 25 | elif [[ ${GATEWAY_OR_TWS@L} = "gateway" ]]; then 26 | command='-g' 27 | elif [[ ${GATEWAY_OR_TWS@L} = "tws" ]]; then 28 | command= 29 | else 30 | printf "GATEWAY_OR_TWS must be either 'gateway' or 'tws': got '%s'\n" "$GATEWAY_OR_TWS" 31 | exit 1 32 | fi 33 | 34 | # Forward correct port with socat 35 | if [[ ${GATEWAY_OR_TWS@L} = "gateway" ]]; then 36 | if [[ ${IBC_TradingMode:-live} = "live" ]]; then 37 | # IBGateway Live 38 | port=4001 39 | else 40 | # IBGateway Paper 41 | port=4002 42 | fi 43 | elif [[ ${IBC_TradingMode:-live} = "live" ]]; then 44 | # TWS Live 45 | port=7496 46 | else 47 | # TWS Paper 48 | port=7497 49 | fi 50 | 51 | printf "Listening for incoming API connections on %s\n" $port 52 | socat -d -d TCP-LISTEN:8888,fork TCP:127.0.0.1:${port} & 53 | 54 | # Hacky way to get the major version for IB Gateway/TWS 55 | TWS_MAJOR_VERSION=$(ls ~/Jts/ibgateway/.) 56 | 57 | # Override /opt/ibc/config.ini with environment variables 58 | ./replace.sh ~/ibc/config.ini 59 | 60 | # --on2fatimeout was previously supplied by gatewaystart.sh/twsstart.sh, 61 | # so we need to supply it here. The rest of the arguments can be read from 62 | # the config.ini file. 63 | 64 | exec /opt/ibc/scripts/ibcstart.sh "${TWS_MAJOR_VERSION}" $command \ 65 | "--user=${USERNAME:-}" \ 66 | "--pw=${PASSWORD:-}" \ 67 | "--on2fatimeout=${TWOFA_TIMEOUT_ACTION:-restart}" \ 68 | "--tws-settings-path=${TWS_SETTINGS_PATH:-}" 69 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: "Build and Publish Docker Images" 2 | 3 | on: 4 | push: 5 | tags: 6 | - "docker-*" 7 | workflow_call: 8 | inputs: 9 | tag: 10 | required: true 11 | type: string 12 | 13 | # Triggers building, tagging and pushing of Docker image files 14 | # Uses tag name to extract channel (latest/stable) 15 | # e.g. docker-10.21.1p-latest -> latest 16 | 17 | jobs: 18 | publish-docker: 19 | name: Publish Docker Image 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: Checkout source code 23 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 24 | with: 25 | # Checkout branch which triggered the action 26 | ref: ${{ github.ref }} 27 | 28 | - name: Extract Channel from workflow input, else tag name 29 | id: channel 30 | run: | 31 | channel=$(cut -d - -f 3 <<< "${{ inputs.tag || github.ref_name }}") 32 | echo "channel=$channel" >> $GITHUB_OUTPUT 33 | 34 | - name: Generate image tags from push tags/workflow input 35 | id: meta 36 | uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5 37 | with: 38 | images: ghcr.io/extrange/ibkr 39 | flavor: | 40 | latest=false 41 | 42 | # Tags for major, major.minor and stable/latest 43 | # Extracted from either pushed tag, or inputs.tag if called from workflow 44 | # https://github.com/docker/metadata-action/blob/8e5442c4ef9f78752691e2d8f8d19755c6f78e81/src/meta.ts#L230-L233 45 | tags: | 46 | type=match,pattern=docker-(\d+.\d+),group=1,value=${{ inputs.tag}} 47 | type=match,pattern=docker-(\d+.\d+.\w+),group=1,value=${{ inputs.tag}} 48 | type=match,pattern=docker-(\d+.\d+.\w+)+\-(stable|latest),group=2,value=${{ inputs.tag}} 49 | 50 | - name: Log in to the Container registry 51 | uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3 52 | with: 53 | registry: ghcr.io 54 | username: ${{ github.actor }} 55 | password: ${{ secrets.GITHUB_TOKEN }} 56 | 57 | - name: Build and push 58 | uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6 59 | with: 60 | # Build context 61 | context: ${{ steps.channel.outputs.channel }} 62 | push: true 63 | tags: ${{ steps.meta.outputs.tags }} 64 | labels: ${{ steps.meta.outputs.labels }} 65 | -------------------------------------------------------------------------------- /.github/workflows/detect-releases.yml: -------------------------------------------------------------------------------- 1 | name: Detect, Test and Publish IB Gateway/TWS Releases 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | channel: 7 | required: true 8 | type: string 9 | 10 | jobs: 11 | check-new-version: 12 | name: Check for new IBKR stable/latest versions 13 | runs-on: ubuntu-latest 14 | outputs: 15 | build_version: ${{ steps.version.outputs.build_version }} 16 | tag: docker-${{ steps.version.outputs.build_version }}-${{ inputs.channel }} 17 | has_update: ${{ steps.check-update.outputs.has_update }} 18 | steps: 19 | - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 20 | 21 | - name: Get Latest IB Gateway Version 22 | id: version 23 | run: | 24 | res=$(curl -s https://download2.interactivebrokers.com/installers/ibgateway/${{ inputs.channel }}-standalone/version.json) 25 | build_version=$(grep -oP '(?<=buildVersion":")[^"]+' <<< "$res") 26 | echo "build_version=$build_version" >> $GITHUB_OUTPUT 27 | 28 | - name: Check Latest Version against Releases 29 | id: check-update 30 | env: 31 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | run: | 33 | if gh release list | grep -qF '${{ steps.version.outputs.build_version }}-${{ inputs.channel }}'; then 34 | echo "has_update=false" >> $GITHUB_OUTPUT 35 | else 36 | echo "has_update=true" >> $GITHUB_OUTPUT 37 | fi 38 | 39 | test-and-commit: 40 | name: Test version and commit 41 | runs-on: ubuntu-latest 42 | needs: check-new-version 43 | if: needs.check-new-version.outputs.has_update == 'true' 44 | steps: 45 | - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 46 | 47 | - name: Download IB Gateway 48 | run: | 49 | download_url='https://download2.interactivebrokers.com/installers/ibgateway/${{ inputs.channel }}-standalone/ibgateway-${{ inputs.channel }}-standalone-linux-x64.sh' 50 | dest='ibgateway-${{ needs.check-new-version.outputs.build_version }}-standalone-linux-x64.sh' 51 | curl -sSL "$download_url" --output "$dest" 52 | sha256sum "$dest" > "${dest}.sha256" 53 | 54 | - name: Create release 55 | env: 56 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 57 | run: | 58 | gh release create '${{ needs.check-new-version.outputs.build_version }}-${{ inputs.channel }}' \ 59 | -t 'ibgateway ${{ needs.check-new-version.outputs.build_version }}-${{ inputs.channel }}' \ 60 | ibgateway-* 61 | rm ibgateway-* 62 | 63 | - name: Update ${{ inputs.channel }}/ 64 | run: ./build.sh ${{ inputs.channel }} ${{ needs.check-new-version.outputs.build_version }} 65 | 66 | # - name: Set up Python 67 | # uses: actions/setup-python@v5 68 | # with: 69 | # python-version: "3.x" 70 | 71 | # - name: Set up pdm 72 | # run: curl -sSL https://pdm-project.org/install-pdm.py | python3 - 73 | 74 | # - name: Update and sync dependencies 75 | # run: pdm update -u 76 | 77 | # - name: Build Docker image 78 | # run: | 79 | # docker build ${{ inputs.channel }} -t image 80 | 81 | # - name: Test ${{ inputs.channel }} 82 | # run: ./start-docker.sh && docker ps && pdm run pytest 83 | # env: 84 | # USERNAME: ${{ secrets.USERNAME }} 85 | # PASSWORD: ${{ secrets.PASSWORD }} 86 | 87 | - name: Commit with appropriate docker tag 88 | uses: stefanzweifel/git-auto-commit-action@28e16e81777b558cc906c8750092100bbb34c5e3 # v7 89 | with: 90 | commit_message: Update ${{ inputs.channel }} to ${{ needs.check-new-version.outputs.build_version }} 91 | 92 | # By itself, will not trigger docker.yml action due to Github restrictions 93 | tagging_message: ${{ needs.check-new-version.outputs.tag }} 94 | 95 | build: 96 | name: Trigger Docker Build Action 97 | needs: 98 | - test-and-commit 99 | - check-new-version 100 | uses: ./.github/workflows/docker.yml 101 | with: 102 | tag: ${{ needs.check-new-version.outputs.tag }} 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Interactive Brokers in Docker 2 | 3 | 4 | 5 | - [Interactive Brokers in Docker](#interactive-brokers-in-docker) 6 | - [Features](#features) 7 | - [Getting Started](#getting-started) 8 | - [Using `docker run`](#using-docker-run) 9 | - [Using `docker compose` (recommended)](#using-docker-compose-recommended) 10 | - [Environment Variables](#environment-variables) 11 | - [Docker Images](#docker-images) 12 | - [FAQ](#faq) 13 | - [How do I save TWS settings locally?](#how-do-i-save-tws-settings-locally) 14 | - [Cannot connect to API when using TWS](#cannot-connect-to-api-when-using-tws) 15 | - [Error: `library initialization failed - unable to allocate file descriptor table - out of memory/root/ibc/scripts/ibcstart.sh`](#error-library-initialization-failed---unable-to-allocate-file-descriptor-table---out-of-memoryrootibcscriptsibcstartsh) 16 | - [Which tag to use, `latest` or `stable`?](#which-tag-to-use-latest-or-stable) 17 | - [What is the difference between IB Gateway and Trader Workstation (TWS)?](#what-is-the-difference-between-ib-gateway-and-trader-workstation-tws) 18 | - [Do I need to download TWS separately?](#do-i-need-to-download-tws-separately) 19 | - [What ports does TWS/IB Gateway use internally?](#what-ports-does-twsib-gateway-use-internally) 20 | - [How do I configure the default login to paper/live trading?](#how-do-i-configure-the-default-login-to-paperlive-trading) 21 | - [Repository Architecture](#repository-architecture) 22 | 23 | 24 | 25 | 26 | 27 | 28 | **Trader Workstation** 29 | 30 | ![](tws.jpg) 31 | 32 | **IB Gateway** 33 | 34 | ![](ibgateway.jpg) 35 | 36 | ## Features 37 | 38 | - **Fully containerized** TWS/IB Gateway, no external dependencies 39 | - [**TWS API access**][tws-api] automatically configured and forwarded 40 | - **Viewable in a browser** (via noVNC) 41 | - **Auto-restart, auto-login** TWS/IB Gateway automatically via [IBC Alpha](https://github.com/IbcAlpha) 42 | 43 | ## Getting Started 44 | 45 | ### Using `docker run` 46 | 47 | ```bash 48 | docker run -d \ 49 | -p "127.0.0.1:6080:6080" \ 50 | -p "127.0.0.1:8888:8888" \ 51 | --ulimit nofile=10000 \ 52 | -e USERNAME=your_username \ 53 | -e PASSWORD=your_password \ 54 | ghcr.io/extrange/ibkr:latest 55 | ``` 56 | 57 | ### Using `docker compose` (recommended) 58 | 59 | Create a `.env` file: 60 | 61 | ```bash 62 | USERNAME= 63 | # wrap password in single quotes if $, /, or \ are present 64 | PASSWORD='' 65 | ``` 66 | 67 | `compose.yml`: 68 | 69 | ```yml 70 | --- 71 | services: 72 | ibkr: 73 | image: ghcr.io/extrange/ibkr # latest, stable, 10.21, 10.21.1p etc 74 | ports: 75 | - "127.0.0.1:6080:6080" # noVNC browser access 76 | - "127.0.0.1:8888:8888" # API access 77 | ulimits: 78 | nofile: 10000 # See FAQ 79 | environment: 80 | USERNAME: ${USERNAME} 81 | PASSWORD: ${PASSWORD} 82 | # TWOFA_TIMEOUT_ACTION: restart 83 | # GATEWAY_OR_TWS: tws 84 | # 85 | # Variables prefixed with IBC_ override IBCAlpha`s config.ini: 86 | # IBC_TradingMode: live 87 | # IBC_ReadOnlyApi: yes 88 | # ... 89 | # See below for more details 90 | ``` 91 | 92 | **Important**: Boolean-like values (e.g. `yes`/`no`) must be wrapped in single quotes to prevent them from being interpreted as `True`/`False` by th YAML parser. 93 | 94 | View at [localhost:6080](http://localhost:6080). 95 | 96 | [TWS API][tws-api] is accessible at port `8888`. 97 | 98 | ### Environment Variables 99 | 100 | | Variable | Description | Default | 101 | |------------------------|------------------------------------------------------------------|------------| 102 | | `USERNAME` | Username | `edemo` | 103 | | `PASSWORD` | Password | `demouser` | 104 | | `GATEWAY_OR_TWS` | What to start, either `tws` or `gateway` | `tws` | 105 | | `TWOFA_TIMEOUT_ACTION` | [2FA timeout action][twofa-timeout]. Either `restart` or `exit`. | `restart` | 106 | | `TWS_SETTINGS_PATH` | (optional) Path to store TWS settings (see FAQ) | | 107 | 108 | Variables prefixed with `IBC_` will override settings in [IBCAlpha][ibc-alpha]'s `config.ini`, e.g.: 109 | 110 | - `IBC_TradingMode` (default: `live`) 111 | - `IBC_ExistingSessionDetectedAction` (default: `manual`) 112 | - `IBC_ReadOnlyApi` (default: keep existing) 113 | - etc. 114 | 115 | See possible values [here][config.ini]. 116 | 117 | ## Docker Images 118 | 119 | See available tags and versions [here.][images] 120 | 121 | ## FAQ 122 | 123 | ### How do I save TWS settings locally? 124 | 125 | If you want to save TWS settings locally (e.g. to persist settings across container runs), set `TWS_SETTINGS_PATH` to say, `/settings`. Then, add a bind mount on your local filesystem, such as in the following `compose.yml`: 126 | 127 | ```yaml 128 | #... 129 | environment: 130 | TWS_SETTINGS_PATH: /settings 131 | #... 132 | volumes: 133 | - ./settings:/settings:rw 134 | ``` 135 | 136 | Now, TWS will load settings from your local filesystem for each container run. 137 | 138 | ### Cannot connect to API when using TWS 139 | 140 | You will need to manually enable `Enable ActiveX and Socket Clients` (see this [issue][tws-api-issue]). 141 | 142 | ### Error: `library initialization failed - unable to allocate file descriptor table - out of memory/root/ibc/scripts/ibcstart.sh` 143 | 144 | Ensure that you have the appropriate `ulimit nofile` set: either `--ulimit nofile=10000` (`docker run`) or `ulimits: nofile: 10000` (`docker compose`). 145 | 146 | ### Which tag to use, `latest` or `stable`? 147 | 148 | `stable` is generally [preferred][stable-or-latest] as there are less bugs. 149 | 150 | ### What is the difference between IB Gateway and Trader Workstation (TWS)? 151 | 152 | [TWS][tws] is a fully featured trading platform with many features. 153 | 154 | [IB Gateway][ibgateway] has a minimal GUI and is used for API access to the trading platform, for example with automated trading. It also uses less resources. 155 | 156 | See [here][tws-vs-gateway] for more differences. 157 | 158 | ### Do I need to download TWS separately? 159 | 160 | Both the IB Gateway and TWS installation scripts include both IB Gateway and TWS, so downloading either is fine. 161 | 162 | ### What ports does TWS/IB Gateway use internally? 163 | 164 | [TWS uses `7496` (live) and `7497` (paper), while IB gateway uses `4001` (live) and `4002` (paper).][tws-ports] 165 | 166 | There is no need to change the port for this image, as it automatically forwards the correct port (based on trading mode and TWS/IB Gateway) to 8888. 167 | 168 | ### How do I configure the default login to paper/live trading? 169 | 170 | Set the environment variable `IBC_TradingMode` to `paper` or `live`. 171 | 172 | ## Repository Architecture 173 | 174 | - New versions of IB Gateway are checked for daily, and fetched if available, as a release (`detect-releases.yml`). 175 | - A PR with the updated `Dockerfile` (obtained by running `build.sh `) is automatically created 176 | - I test the updated configuration (both IB Gateway/TWS) 177 | - I then manually merge the PR, and tag the resulting commit with `git tag docker--` 178 | - Pushing the tag triggers a docker build action (`publish.yml`, based on the `docker-` prefix), which reads the version and release channel (latest/stable) from the tag, and then fetches the repo at the tag's commit, builds from the appropriate folder (latest/stable), tags and pushes the image to [ghcr.io/extrange/ibkr][images]. 179 | 180 | [images]: https://github.com/extrange/ibkr-docker/pkgs/container/ibkr 181 | [tws-api]: https://interactivebrokers.github.io/tws-api/introduction.html 182 | [ibc-alpha]: https://github.com/IbcAlpha 183 | [config.ini]: https://github.com/IbcAlpha/IBC/blob/master/resources/config.ini 184 | [twofa-timeout]: https://github.com/IbcAlpha/IBC/blob/master/userguide.md#second-factor-authentication 185 | [stable-or-latest]: https://github.com/IbcAlpha/IBC/blob/master/userguide.md#interactive-brokers-trader-workstation 186 | [tws]: https://www.interactivebrokers.com/en/trading/tws.php 187 | [ibgateway]: https://www.interactivebrokers.com/en/trading/ibgateway-stable.php 188 | [tws-vs-gateway]: https://stackoverflow.com/questions/32778954/interactive-brokers-api-trader-workstation-tws-vs-ib-gateway 189 | [tws-ports]: https://www.interactivebrokers.com/en/?f=%2Fen%2Fgeneral%2Ftws-notes-954.php 190 | [tws-api-issue]: https://github.com/extrange/ibkr-docker/issues/16#issuecomment-1514830115 191 | -------------------------------------------------------------------------------- /uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | revision = 2 3 | requires-python = ">=3.12" 4 | 5 | [[package]] 6 | name = "appnope" 7 | version = "0.1.4" 8 | source = { registry = "https://pypi.org/simple" } 9 | sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } 10 | wheels = [ 11 | { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, 12 | ] 13 | 14 | [[package]] 15 | name = "asttokens" 16 | version = "3.0.0" 17 | source = { registry = "https://pypi.org/simple" } 18 | sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } 19 | wheels = [ 20 | { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, 21 | ] 22 | 23 | [[package]] 24 | name = "cffi" 25 | version = "1.17.1" 26 | source = { registry = "https://pypi.org/simple" } 27 | dependencies = [ 28 | { name = "pycparser" }, 29 | ] 30 | sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } 31 | wheels = [ 32 | { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, 33 | { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, 34 | { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, 35 | { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, 36 | { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, 37 | { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, 38 | { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, 39 | { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, 40 | { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, 41 | { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, 42 | { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, 43 | { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, 44 | { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, 45 | { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, 46 | { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, 47 | { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, 48 | { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, 49 | { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, 50 | { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, 51 | { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, 52 | { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, 53 | { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, 54 | ] 55 | 56 | [[package]] 57 | name = "colorama" 58 | version = "0.4.6" 59 | source = { registry = "https://pypi.org/simple" } 60 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } 61 | wheels = [ 62 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, 63 | ] 64 | 65 | [[package]] 66 | name = "comm" 67 | version = "0.2.2" 68 | source = { registry = "https://pypi.org/simple" } 69 | dependencies = [ 70 | { name = "traitlets" }, 71 | ] 72 | sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210, upload-time = "2024-03-12T16:53:41.133Z" } 73 | wheels = [ 74 | { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180, upload-time = "2024-03-12T16:53:39.226Z" }, 75 | ] 76 | 77 | [[package]] 78 | name = "debugpy" 79 | version = "1.8.14" 80 | source = { registry = "https://pypi.org/simple" } 81 | sdist = { url = "https://files.pythonhosted.org/packages/bd/75/087fe07d40f490a78782ff3b0a30e3968936854105487decdb33446d4b0e/debugpy-1.8.14.tar.gz", hash = "sha256:7cd287184318416850aa8b60ac90105837bb1e59531898c07569d197d2ed5322", size = 1641444, upload-time = "2025-04-10T19:46:10.981Z" } 82 | wheels = [ 83 | { url = "https://files.pythonhosted.org/packages/d9/2a/ac2df0eda4898f29c46eb6713a5148e6f8b2b389c8ec9e425a4a1d67bf07/debugpy-1.8.14-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:8899c17920d089cfa23e6005ad9f22582fd86f144b23acb9feeda59e84405b84", size = 2501268, upload-time = "2025-04-10T19:46:26.044Z" }, 84 | { url = "https://files.pythonhosted.org/packages/10/53/0a0cb5d79dd9f7039169f8bf94a144ad3efa52cc519940b3b7dde23bcb89/debugpy-1.8.14-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6bb5c0dcf80ad5dbc7b7d6eac484e2af34bdacdf81df09b6a3e62792b722826", size = 4221077, upload-time = "2025-04-10T19:46:27.464Z" }, 85 | { url = "https://files.pythonhosted.org/packages/f8/d5/84e01821f362327bf4828728aa31e907a2eca7c78cd7c6ec062780d249f8/debugpy-1.8.14-cp312-cp312-win32.whl", hash = "sha256:281d44d248a0e1791ad0eafdbbd2912ff0de9eec48022a5bfbc332957487ed3f", size = 5255127, upload-time = "2025-04-10T19:46:29.467Z" }, 86 | { url = "https://files.pythonhosted.org/packages/33/16/1ed929d812c758295cac7f9cf3dab5c73439c83d9091f2d91871e648093e/debugpy-1.8.14-cp312-cp312-win_amd64.whl", hash = "sha256:5aa56ef8538893e4502a7d79047fe39b1dae08d9ae257074c6464a7b290b806f", size = 5297249, upload-time = "2025-04-10T19:46:31.538Z" }, 87 | { url = "https://files.pythonhosted.org/packages/4d/e4/395c792b243f2367d84202dc33689aa3d910fb9826a7491ba20fc9e261f5/debugpy-1.8.14-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:329a15d0660ee09fec6786acdb6e0443d595f64f5d096fc3e3ccf09a4259033f", size = 2485676, upload-time = "2025-04-10T19:46:32.96Z" }, 88 | { url = "https://files.pythonhosted.org/packages/ba/f1/6f2ee3f991327ad9e4c2f8b82611a467052a0fb0e247390192580e89f7ff/debugpy-1.8.14-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f920c7f9af409d90f5fd26e313e119d908b0dd2952c2393cd3247a462331f15", size = 4217514, upload-time = "2025-04-10T19:46:34.336Z" }, 89 | { url = "https://files.pythonhosted.org/packages/79/28/b9d146f8f2dc535c236ee09ad3e5ac899adb39d7a19b49f03ac95d216beb/debugpy-1.8.14-cp313-cp313-win32.whl", hash = "sha256:3784ec6e8600c66cbdd4ca2726c72d8ca781e94bce2f396cc606d458146f8f4e", size = 5254756, upload-time = "2025-04-10T19:46:36.199Z" }, 90 | { url = "https://files.pythonhosted.org/packages/e0/62/a7b4a57013eac4ccaef6977966e6bec5c63906dd25a86e35f155952e29a1/debugpy-1.8.14-cp313-cp313-win_amd64.whl", hash = "sha256:684eaf43c95a3ec39a96f1f5195a7ff3d4144e4a18d69bb66beeb1a6de605d6e", size = 5297119, upload-time = "2025-04-10T19:46:38.141Z" }, 91 | { url = "https://files.pythonhosted.org/packages/97/1a/481f33c37ee3ac8040d3d51fc4c4e4e7e61cb08b8bc8971d6032acc2279f/debugpy-1.8.14-py2.py3-none-any.whl", hash = "sha256:5cd9a579d553b6cb9759a7908a41988ee6280b961f24f63336835d9418216a20", size = 5256230, upload-time = "2025-04-10T19:46:54.077Z" }, 92 | ] 93 | 94 | [[package]] 95 | name = "decorator" 96 | version = "5.2.1" 97 | source = { registry = "https://pypi.org/simple" } 98 | sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } 99 | wheels = [ 100 | { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, 101 | ] 102 | 103 | [[package]] 104 | name = "eventkit" 105 | version = "1.0.3" 106 | source = { registry = "https://pypi.org/simple" } 107 | dependencies = [ 108 | { name = "numpy" }, 109 | ] 110 | sdist = { url = "https://files.pythonhosted.org/packages/16/1e/0fac4e45d71ace143a2673ec642701c3cd16f833a0e77a57fa6a40472696/eventkit-1.0.3.tar.gz", hash = "sha256:99497f6f3c638a50ff7616f2f8cd887b18bbff3765dc1bd8681554db1467c933", size = 28320, upload-time = "2023-12-11T11:41:35.339Z" } 111 | wheels = [ 112 | { url = "https://files.pythonhosted.org/packages/93/d9/7497d650b69b420e1a913329a843e16c715dac883750679240ef00a921e2/eventkit-1.0.3-py3-none-any.whl", hash = "sha256:0e199527a89aff9d195b9671ad45d2cc9f79ecda0900de8ecfb4c864d67ad6a2", size = 31837, upload-time = "2023-12-11T11:41:33.358Z" }, 113 | ] 114 | 115 | [[package]] 116 | name = "executing" 117 | version = "2.2.0" 118 | source = { registry = "https://pypi.org/simple" } 119 | sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693, upload-time = "2025-01-22T15:41:29.403Z" } 120 | wheels = [ 121 | { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload-time = "2025-01-22T15:41:25.929Z" }, 122 | ] 123 | 124 | [[package]] 125 | name = "ib-insync" 126 | version = "0.9.86" 127 | source = { registry = "https://pypi.org/simple" } 128 | dependencies = [ 129 | { name = "eventkit" }, 130 | { name = "nest-asyncio" }, 131 | ] 132 | sdist = { url = "https://files.pythonhosted.org/packages/55/bb/733d5c81c8c2f54e90898afc7ff3a99f4d53619e6917c848833f9cc1ab56/ib_insync-0.9.86.tar.gz", hash = "sha256:73af602ca2463f260999970c5bd937b1c4325e383686eff301743a4de08d381e", size = 69859, upload-time = "2023-07-02T12:43:31.968Z" } 133 | wheels = [ 134 | { url = "https://files.pythonhosted.org/packages/8f/f3/28ea87be30570f4d6b8fd24380d12fa74e59467ee003755e76aeb29082b8/ib_insync-0.9.86-py3-none-any.whl", hash = "sha256:a61fbe56ff405d93d211dad8238d7300de76dd6399eafc04c320470edec9a4a4", size = 72980, upload-time = "2023-07-02T12:43:29.928Z" }, 135 | ] 136 | 137 | [[package]] 138 | name = "ibkr-docker" 139 | version = "0.1.0" 140 | source = { virtual = "." } 141 | dependencies = [ 142 | { name = "ib-insync" }, 143 | ] 144 | 145 | [package.dev-dependencies] 146 | dev = [ 147 | { name = "ipykernel" }, 148 | { name = "pyright", extra = ["nodejs"] }, 149 | { name = "pytest" }, 150 | { name = "ruff" }, 151 | ] 152 | 153 | [package.metadata] 154 | requires-dist = [{ name = "ib-insync", specifier = ">=0.9.86" }] 155 | 156 | [package.metadata.requires-dev] 157 | dev = [ 158 | { name = "ipykernel", specifier = ">=6.29.5" }, 159 | { name = "pyright", extras = ["nodejs"], specifier = ">=1.1.382.post0" }, 160 | { name = "pytest", specifier = ">=8.3.3" }, 161 | { name = "ruff", specifier = ">=0.6.8" }, 162 | ] 163 | 164 | [[package]] 165 | name = "iniconfig" 166 | version = "2.1.0" 167 | source = { registry = "https://pypi.org/simple" } 168 | sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } 169 | wheels = [ 170 | { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, 171 | ] 172 | 173 | [[package]] 174 | name = "ipykernel" 175 | version = "6.29.5" 176 | source = { registry = "https://pypi.org/simple" } 177 | dependencies = [ 178 | { name = "appnope", marker = "sys_platform == 'darwin'" }, 179 | { name = "comm" }, 180 | { name = "debugpy" }, 181 | { name = "ipython" }, 182 | { name = "jupyter-client" }, 183 | { name = "jupyter-core" }, 184 | { name = "matplotlib-inline" }, 185 | { name = "nest-asyncio" }, 186 | { name = "packaging" }, 187 | { name = "psutil" }, 188 | { name = "pyzmq" }, 189 | { name = "tornado" }, 190 | { name = "traitlets" }, 191 | ] 192 | sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367, upload-time = "2024-07-01T14:07:22.543Z" } 193 | wheels = [ 194 | { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173, upload-time = "2024-07-01T14:07:19.603Z" }, 195 | ] 196 | 197 | [[package]] 198 | name = "ipython" 199 | version = "9.3.0" 200 | source = { registry = "https://pypi.org/simple" } 201 | dependencies = [ 202 | { name = "colorama", marker = "sys_platform == 'win32'" }, 203 | { name = "decorator" }, 204 | { name = "ipython-pygments-lexers" }, 205 | { name = "jedi" }, 206 | { name = "matplotlib-inline" }, 207 | { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, 208 | { name = "prompt-toolkit" }, 209 | { name = "pygments" }, 210 | { name = "stack-data" }, 211 | { name = "traitlets" }, 212 | ] 213 | sdist = { url = "https://files.pythonhosted.org/packages/dc/09/4c7e06b96fbd203e06567b60fb41b06db606b6a82db6db7b2c85bb72a15c/ipython-9.3.0.tar.gz", hash = "sha256:79eb896f9f23f50ad16c3bc205f686f6e030ad246cc309c6279a242b14afe9d8", size = 4426460, upload-time = "2025-05-31T16:34:55.678Z" } 214 | wheels = [ 215 | { url = "https://files.pythonhosted.org/packages/3c/99/9ed3d52d00f1846679e3aa12e2326ac7044b5e7f90dc822b60115fa533ca/ipython-9.3.0-py3-none-any.whl", hash = "sha256:1a0b6dd9221a1f5dddf725b57ac0cb6fddc7b5f470576231ae9162b9b3455a04", size = 605320, upload-time = "2025-05-31T16:34:52.154Z" }, 216 | ] 217 | 218 | [[package]] 219 | name = "ipython-pygments-lexers" 220 | version = "1.1.1" 221 | source = { registry = "https://pypi.org/simple" } 222 | dependencies = [ 223 | { name = "pygments" }, 224 | ] 225 | sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } 226 | wheels = [ 227 | { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, 228 | ] 229 | 230 | [[package]] 231 | name = "jedi" 232 | version = "0.19.2" 233 | source = { registry = "https://pypi.org/simple" } 234 | dependencies = [ 235 | { name = "parso" }, 236 | ] 237 | sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } 238 | wheels = [ 239 | { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, 240 | ] 241 | 242 | [[package]] 243 | name = "jupyter-client" 244 | version = "8.6.3" 245 | source = { registry = "https://pypi.org/simple" } 246 | dependencies = [ 247 | { name = "jupyter-core" }, 248 | { name = "python-dateutil" }, 249 | { name = "pyzmq" }, 250 | { name = "tornado" }, 251 | { name = "traitlets" }, 252 | ] 253 | sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019, upload-time = "2024-09-17T10:44:17.613Z" } 254 | wheels = [ 255 | { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105, upload-time = "2024-09-17T10:44:15.218Z" }, 256 | ] 257 | 258 | [[package]] 259 | name = "jupyter-core" 260 | version = "5.8.1" 261 | source = { registry = "https://pypi.org/simple" } 262 | dependencies = [ 263 | { name = "platformdirs" }, 264 | { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, 265 | { name = "traitlets" }, 266 | ] 267 | sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload-time = "2025-05-27T07:38:16.655Z" } 268 | wheels = [ 269 | { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload-time = "2025-05-27T07:38:15.137Z" }, 270 | ] 271 | 272 | [[package]] 273 | name = "matplotlib-inline" 274 | version = "0.1.7" 275 | source = { registry = "https://pypi.org/simple" } 276 | dependencies = [ 277 | { name = "traitlets" }, 278 | ] 279 | sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } 280 | wheels = [ 281 | { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, 282 | ] 283 | 284 | [[package]] 285 | name = "nest-asyncio" 286 | version = "1.6.0" 287 | source = { registry = "https://pypi.org/simple" } 288 | sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } 289 | wheels = [ 290 | { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, 291 | ] 292 | 293 | [[package]] 294 | name = "nodeenv" 295 | version = "1.9.1" 296 | source = { registry = "https://pypi.org/simple" } 297 | sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } 298 | wheels = [ 299 | { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, 300 | ] 301 | 302 | [[package]] 303 | name = "nodejs-wheel-binaries" 304 | version = "22.16.0" 305 | source = { registry = "https://pypi.org/simple" } 306 | sdist = { url = "https://files.pythonhosted.org/packages/0f/c6/66f36b7b0d528660dfb4a59cb9b8dd6a3f4c0a3939cd49c404a775ea4a63/nodejs_wheel_binaries-22.16.0.tar.gz", hash = "sha256:d695832f026df3a0cf9a089d222225939de9d1b67f8f0a353b79f015aabbe7e2", size = 8061, upload-time = "2025-05-22T07:27:52.149Z" } 307 | wheels = [ 308 | { url = "https://files.pythonhosted.org/packages/d7/dc/417a5c5f99e53a5d2b3be122506312731eb90fb9630c248e327e2e38cc6b/nodejs_wheel_binaries-22.16.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:986b715a96ed703f8ce0c15712f76fc42895cf09067d72b6ef29e8b334eccf64", size = 50957501, upload-time = "2025-05-22T07:27:20.132Z" }, 309 | { url = "https://files.pythonhosted.org/packages/0e/dd/d6ce48209ed15f5d1fccb29eeaa111f962557123eaf4fd03a7316c42734c/nodejs_wheel_binaries-22.16.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:4ae3cf22138891cb44c3ee952862a257ce082b098b29024d7175684a9a77b0c0", size = 51891634, upload-time = "2025-05-22T07:27:24.029Z" }, 310 | { url = "https://files.pythonhosted.org/packages/80/fa/a07e622fd87717eec3e5cff41575f85ad62717e8698884d28ca809266ca1/nodejs_wheel_binaries-22.16.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71f2de4dc0b64ae43e146897ce811f80ac4f9acfbae6ccf814226282bf4ef174", size = 57857862, upload-time = "2025-05-22T07:27:27.933Z" }, 311 | { url = "https://files.pythonhosted.org/packages/1f/80/52736f9570a93f8e6b7942981dc9770eca2bc7aa1d200c1d54198374a6ca/nodejs_wheel_binaries-22.16.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbfccbcd558d2f142ccf66d8c3a098022bf4436db9525b5b8d32169ce185d99e", size = 58395868, upload-time = "2025-05-22T07:27:32.088Z" }, 312 | { url = "https://files.pythonhosted.org/packages/0f/0e/53616a5ed8fc1fbe9e48bf132862da5a9abf5cc7f8483dab1722ec257187/nodejs_wheel_binaries-22.16.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:447ad796850eb52ca20356ad39b2d296ed8fef3f214921f84a1ccdad49f2eba1", size = 59712469, upload-time = "2025-05-22T07:27:37.193Z" }, 313 | { url = "https://files.pythonhosted.org/packages/4a/cd/e2b5083df581fc1d08eb93feb6f8fbd3d56b113cef9b59d8e0fb7d4dd4f3/nodejs_wheel_binaries-22.16.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7f526ca6a132b0caf633566a2a78c6985fe92857e7bfdb37380f76205a10b808", size = 60763005, upload-time = "2025-05-22T07:27:41.39Z" }, 314 | { url = "https://files.pythonhosted.org/packages/71/8d/57112b49214e8bd636f3cc3386eba6be4d23552ec8a0f6efbe814013caa7/nodejs_wheel_binaries-22.16.0-py2.py3-none-win_amd64.whl", hash = "sha256:2fffb4bf1066fb5f660da20819d754f1b424bca1b234ba0f4fa901c52e3975fb", size = 41313324, upload-time = "2025-05-22T07:27:45.293Z" }, 315 | { url = "https://files.pythonhosted.org/packages/91/03/a852711aec73dfb965844592dfe226024c0da28e37d1ee54083342e38f57/nodejs_wheel_binaries-22.16.0-py2.py3-none-win_arm64.whl", hash = "sha256:2728972d336d436d39ee45988978d8b5d963509e06f063e80fe41b203ee80b28", size = 38828154, upload-time = "2025-05-22T07:27:48.606Z" }, 316 | ] 317 | 318 | [[package]] 319 | name = "numpy" 320 | version = "2.3.0" 321 | source = { registry = "https://pypi.org/simple" } 322 | sdist = { url = "https://files.pythonhosted.org/packages/f3/db/8e12381333aea300890829a0a36bfa738cac95475d88982d538725143fd9/numpy-2.3.0.tar.gz", hash = "sha256:581f87f9e9e9db2cba2141400e160e9dd644ee248788d6f90636eeb8fd9260a6", size = 20382813, upload-time = "2025-06-07T14:54:32.608Z" } 323 | wheels = [ 324 | { url = "https://files.pythonhosted.org/packages/89/59/9df493df81ac6f76e9f05cdbe013cdb0c9a37b434f6e594f5bd25e278908/numpy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:389b85335838155a9076e9ad7f8fdba0827496ec2d2dc32ce69ce7898bde03ba", size = 20897025, upload-time = "2025-06-07T14:40:33.558Z" }, 325 | { url = "https://files.pythonhosted.org/packages/2f/86/4ff04335901d6cf3a6bb9c748b0097546ae5af35e455ae9b962ebff4ecd7/numpy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9498f60cd6bb8238d8eaf468a3d5bb031d34cd12556af53510f05fcf581c1b7e", size = 14129882, upload-time = "2025-06-07T14:40:55.034Z" }, 326 | { url = "https://files.pythonhosted.org/packages/71/8d/a942cd4f959de7f08a79ab0c7e6cecb7431d5403dce78959a726f0f57aa1/numpy-2.3.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:622a65d40d8eb427d8e722fd410ac3ad4958002f109230bc714fa551044ebae2", size = 5110181, upload-time = "2025-06-07T14:41:04.4Z" }, 327 | { url = "https://files.pythonhosted.org/packages/86/5d/45850982efc7b2c839c5626fb67fbbc520d5b0d7c1ba1ae3651f2f74c296/numpy-2.3.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:b9446d9d8505aadadb686d51d838f2b6688c9e85636a0c3abaeb55ed54756459", size = 6647581, upload-time = "2025-06-07T14:41:14.695Z" }, 328 | { url = "https://files.pythonhosted.org/packages/1a/c0/c871d4a83f93b00373d3eebe4b01525eee8ef10b623a335ec262b58f4dc1/numpy-2.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:50080245365d75137a2bf46151e975de63146ae6d79f7e6bd5c0e85c9931d06a", size = 14262317, upload-time = "2025-06-07T14:41:35.862Z" }, 329 | { url = "https://files.pythonhosted.org/packages/b7/f6/bc47f5fa666d5ff4145254f9e618d56e6a4ef9b874654ca74c19113bb538/numpy-2.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c24bb4113c66936eeaa0dc1e47c74770453d34f46ee07ae4efd853a2ed1ad10a", size = 16633919, upload-time = "2025-06-07T14:42:00.622Z" }, 330 | { url = "https://files.pythonhosted.org/packages/f5/b4/65f48009ca0c9b76df5f404fccdea5a985a1bb2e34e97f21a17d9ad1a4ba/numpy-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4d8d294287fdf685281e671886c6dcdf0291a7c19db3e5cb4178d07ccf6ecc67", size = 15567651, upload-time = "2025-06-07T14:42:24.429Z" }, 331 | { url = "https://files.pythonhosted.org/packages/f1/62/5367855a2018578e9334ed08252ef67cc302e53edc869666f71641cad40b/numpy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6295f81f093b7f5769d1728a6bd8bf7466de2adfa771ede944ce6711382b89dc", size = 18361723, upload-time = "2025-06-07T14:42:51.167Z" }, 332 | { url = "https://files.pythonhosted.org/packages/d4/75/5baed8cd867eabee8aad1e74d7197d73971d6a3d40c821f1848b8fab8b84/numpy-2.3.0-cp312-cp312-win32.whl", hash = "sha256:e6648078bdd974ef5d15cecc31b0c410e2e24178a6e10bf511e0557eed0f2570", size = 6318285, upload-time = "2025-06-07T14:43:02.052Z" }, 333 | { url = "https://files.pythonhosted.org/packages/bc/49/d5781eaa1a15acb3b3a3f49dc9e2ff18d92d0ce5c2976f4ab5c0a7360250/numpy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:0898c67a58cdaaf29994bc0e2c65230fd4de0ac40afaf1584ed0b02cd74c6fdd", size = 12732594, upload-time = "2025-06-07T14:43:21.071Z" }, 334 | { url = "https://files.pythonhosted.org/packages/c2/1c/6d343e030815c7c97a1f9fbad00211b47717c7fe446834c224bd5311e6f1/numpy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:bd8df082b6c4695753ad6193018c05aac465d634834dca47a3ae06d4bb22d9ea", size = 9891498, upload-time = "2025-06-07T14:43:36.332Z" }, 335 | { url = "https://files.pythonhosted.org/packages/73/fc/1d67f751fd4dbafc5780244fe699bc4084268bad44b7c5deb0492473127b/numpy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5754ab5595bfa2c2387d241296e0381c21f44a4b90a776c3c1d39eede13a746a", size = 20889633, upload-time = "2025-06-07T14:44:06.839Z" }, 336 | { url = "https://files.pythonhosted.org/packages/e8/95/73ffdb69e5c3f19ec4530f8924c4386e7ba097efc94b9c0aff607178ad94/numpy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d11fa02f77752d8099573d64e5fe33de3229b6632036ec08f7080f46b6649959", size = 14151683, upload-time = "2025-06-07T14:44:28.847Z" }, 337 | { url = "https://files.pythonhosted.org/packages/64/d5/06d4bb31bb65a1d9c419eb5676173a2f90fd8da3c59f816cc54c640ce265/numpy-2.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:aba48d17e87688a765ab1cd557882052f238e2f36545dfa8e29e6a91aef77afe", size = 5102683, upload-time = "2025-06-07T14:44:38.417Z" }, 338 | { url = "https://files.pythonhosted.org/packages/12/8b/6c2cef44f8ccdc231f6b56013dff1d71138c48124334aded36b1a1b30c5a/numpy-2.3.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4dc58865623023b63b10d52f18abaac3729346a7a46a778381e0e3af4b7f3beb", size = 6640253, upload-time = "2025-06-07T14:44:49.359Z" }, 339 | { url = "https://files.pythonhosted.org/packages/62/aa/fca4bf8de3396ddb59544df9b75ffe5b73096174de97a9492d426f5cd4aa/numpy-2.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:df470d376f54e052c76517393fa443758fefcdd634645bc9c1f84eafc67087f0", size = 14258658, upload-time = "2025-06-07T14:45:10.156Z" }, 340 | { url = "https://files.pythonhosted.org/packages/1c/12/734dce1087eed1875f2297f687e671cfe53a091b6f2f55f0c7241aad041b/numpy-2.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:87717eb24d4a8a64683b7a4e91ace04e2f5c7c77872f823f02a94feee186168f", size = 16628765, upload-time = "2025-06-07T14:45:35.076Z" }, 341 | { url = "https://files.pythonhosted.org/packages/48/03/ffa41ade0e825cbcd5606a5669962419528212a16082763fc051a7247d76/numpy-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fa264d56882b59dcb5ea4d6ab6f31d0c58a57b41aec605848b6eb2ef4a43e8", size = 15564335, upload-time = "2025-06-07T14:45:58.797Z" }, 342 | { url = "https://files.pythonhosted.org/packages/07/58/869398a11863310aee0ff85a3e13b4c12f20d032b90c4b3ee93c3b728393/numpy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e651756066a0eaf900916497e20e02fe1ae544187cb0fe88de981671ee7f6270", size = 18360608, upload-time = "2025-06-07T14:46:25.687Z" }, 343 | { url = "https://files.pythonhosted.org/packages/2f/8a/5756935752ad278c17e8a061eb2127c9a3edf4ba2c31779548b336f23c8d/numpy-2.3.0-cp313-cp313-win32.whl", hash = "sha256:e43c3cce3b6ae5f94696669ff2a6eafd9a6b9332008bafa4117af70f4b88be6f", size = 6310005, upload-time = "2025-06-07T14:50:13.138Z" }, 344 | { url = "https://files.pythonhosted.org/packages/08/60/61d60cf0dfc0bf15381eaef46366ebc0c1a787856d1db0c80b006092af84/numpy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:81ae0bf2564cf475f94be4a27ef7bcf8af0c3e28da46770fc904da9abd5279b5", size = 12729093, upload-time = "2025-06-07T14:50:31.82Z" }, 345 | { url = "https://files.pythonhosted.org/packages/66/31/2f2f2d2b3e3c32d5753d01437240feaa32220b73258c9eef2e42a0832866/numpy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:c8738baa52505fa6e82778580b23f945e3578412554d937093eac9205e845e6e", size = 9885689, upload-time = "2025-06-07T14:50:47.888Z" }, 346 | { url = "https://files.pythonhosted.org/packages/f1/89/c7828f23cc50f607ceb912774bb4cff225ccae7131c431398ad8400e2c98/numpy-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:39b27d8b38942a647f048b675f134dd5a567f95bfff481f9109ec308515c51d8", size = 20986612, upload-time = "2025-06-07T14:46:56.077Z" }, 347 | { url = "https://files.pythonhosted.org/packages/dd/46/79ecf47da34c4c50eedec7511e53d57ffdfd31c742c00be7dc1d5ffdb917/numpy-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0eba4a1ea88f9a6f30f56fdafdeb8da3774349eacddab9581a21234b8535d3d3", size = 14298953, upload-time = "2025-06-07T14:47:18.053Z" }, 348 | { url = "https://files.pythonhosted.org/packages/59/44/f6caf50713d6ff4480640bccb2a534ce1d8e6e0960c8f864947439f0ee95/numpy-2.3.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0f1f11d0a1da54927436505a5a7670b154eac27f5672afc389661013dfe3d4f", size = 5225806, upload-time = "2025-06-07T14:47:27.524Z" }, 349 | { url = "https://files.pythonhosted.org/packages/a6/43/e1fd1aca7c97e234dd05e66de4ab7a5be54548257efcdd1bc33637e72102/numpy-2.3.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:690d0a5b60a47e1f9dcec7b77750a4854c0d690e9058b7bef3106e3ae9117808", size = 6735169, upload-time = "2025-06-07T14:47:38.057Z" }, 350 | { url = "https://files.pythonhosted.org/packages/84/89/f76f93b06a03177c0faa7ca94d0856c4e5c4bcaf3c5f77640c9ed0303e1c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8b51ead2b258284458e570942137155978583e407babc22e3d0ed7af33ce06f8", size = 14330701, upload-time = "2025-06-07T14:47:59.113Z" }, 351 | { url = "https://files.pythonhosted.org/packages/aa/f5/4858c3e9ff7a7d64561b20580cf7cc5d085794bd465a19604945d6501f6c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:aaf81c7b82c73bd9b45e79cfb9476cb9c29e937494bfe9092c26aece812818ad", size = 16692983, upload-time = "2025-06-07T14:48:24.196Z" }, 352 | { url = "https://files.pythonhosted.org/packages/08/17/0e3b4182e691a10e9483bcc62b4bb8693dbf9ea5dc9ba0b77a60435074bb/numpy-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f420033a20b4f6a2a11f585f93c843ac40686a7c3fa514060a97d9de93e5e72b", size = 15641435, upload-time = "2025-06-07T14:48:47.712Z" }, 353 | { url = "https://files.pythonhosted.org/packages/4e/d5/463279fda028d3c1efa74e7e8d507605ae87f33dbd0543cf4c4527c8b882/numpy-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d344ca32ab482bcf8735d8f95091ad081f97120546f3d250240868430ce52555", size = 18433798, upload-time = "2025-06-07T14:49:14.866Z" }, 354 | { url = "https://files.pythonhosted.org/packages/0e/1e/7a9d98c886d4c39a2b4d3a7c026bffcf8fbcaf518782132d12a301cfc47a/numpy-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:48a2e8eaf76364c32a1feaa60d6925eaf32ed7a040183b807e02674305beef61", size = 6438632, upload-time = "2025-06-07T14:49:25.67Z" }, 355 | { url = "https://files.pythonhosted.org/packages/fe/ab/66fc909931d5eb230107d016861824f335ae2c0533f422e654e5ff556784/numpy-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ba17f93a94e503551f154de210e4d50c5e3ee20f7e7a1b5f6ce3f22d419b93bb", size = 12868491, upload-time = "2025-06-07T14:49:44.898Z" }, 356 | { url = "https://files.pythonhosted.org/packages/ee/e8/2c8a1c9e34d6f6d600c83d5ce5b71646c32a13f34ca5c518cc060639841c/numpy-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f14e016d9409680959691c109be98c436c6249eaf7f118b424679793607b5944", size = 9935345, upload-time = "2025-06-07T14:50:02.311Z" }, 357 | ] 358 | 359 | [[package]] 360 | name = "packaging" 361 | version = "25.0" 362 | source = { registry = "https://pypi.org/simple" } 363 | sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } 364 | wheels = [ 365 | { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, 366 | ] 367 | 368 | [[package]] 369 | name = "parso" 370 | version = "0.8.4" 371 | source = { registry = "https://pypi.org/simple" } 372 | sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609, upload-time = "2024-04-05T09:43:55.897Z" } 373 | wheels = [ 374 | { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650, upload-time = "2024-04-05T09:43:53.299Z" }, 375 | ] 376 | 377 | [[package]] 378 | name = "pexpect" 379 | version = "4.9.0" 380 | source = { registry = "https://pypi.org/simple" } 381 | dependencies = [ 382 | { name = "ptyprocess" }, 383 | ] 384 | sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } 385 | wheels = [ 386 | { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, 387 | ] 388 | 389 | [[package]] 390 | name = "platformdirs" 391 | version = "4.3.8" 392 | source = { registry = "https://pypi.org/simple" } 393 | sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } 394 | wheels = [ 395 | { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, 396 | ] 397 | 398 | [[package]] 399 | name = "pluggy" 400 | version = "1.6.0" 401 | source = { registry = "https://pypi.org/simple" } 402 | sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } 403 | wheels = [ 404 | { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, 405 | ] 406 | 407 | [[package]] 408 | name = "prompt-toolkit" 409 | version = "3.0.51" 410 | source = { registry = "https://pypi.org/simple" } 411 | dependencies = [ 412 | { name = "wcwidth" }, 413 | ] 414 | sdist = { url = "https://files.pythonhosted.org/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed", size = 428940, upload-time = "2025-04-15T09:18:47.731Z" } 415 | wheels = [ 416 | { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload-time = "2025-04-15T09:18:44.753Z" }, 417 | ] 418 | 419 | [[package]] 420 | name = "psutil" 421 | version = "7.0.0" 422 | source = { registry = "https://pypi.org/simple" } 423 | sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } 424 | wheels = [ 425 | { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, 426 | { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, 427 | { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, 428 | { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, 429 | { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, 430 | { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, 431 | { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, 432 | ] 433 | 434 | [[package]] 435 | name = "ptyprocess" 436 | version = "0.7.0" 437 | source = { registry = "https://pypi.org/simple" } 438 | sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } 439 | wheels = [ 440 | { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, 441 | ] 442 | 443 | [[package]] 444 | name = "pure-eval" 445 | version = "0.2.3" 446 | source = { registry = "https://pypi.org/simple" } 447 | sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } 448 | wheels = [ 449 | { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, 450 | ] 451 | 452 | [[package]] 453 | name = "pycparser" 454 | version = "2.22" 455 | source = { registry = "https://pypi.org/simple" } 456 | sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } 457 | wheels = [ 458 | { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, 459 | ] 460 | 461 | [[package]] 462 | name = "pygments" 463 | version = "2.19.1" 464 | source = { registry = "https://pypi.org/simple" } 465 | sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } 466 | wheels = [ 467 | { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, 468 | ] 469 | 470 | [[package]] 471 | name = "pyright" 472 | version = "1.1.402" 473 | source = { registry = "https://pypi.org/simple" } 474 | dependencies = [ 475 | { name = "nodeenv" }, 476 | { name = "typing-extensions" }, 477 | ] 478 | sdist = { url = "https://files.pythonhosted.org/packages/aa/04/ce0c132d00e20f2d2fb3b3e7c125264ca8b909e693841210534b1ea1752f/pyright-1.1.402.tar.gz", hash = "sha256:85a33c2d40cd4439c66aa946fd4ce71ab2f3f5b8c22ce36a623f59ac22937683", size = 3888207, upload-time = "2025-06-11T08:48:35.759Z" } 479 | wheels = [ 480 | { url = "https://files.pythonhosted.org/packages/fe/37/1a1c62d955e82adae588be8e374c7f77b165b6cb4203f7d581269959abbc/pyright-1.1.402-py3-none-any.whl", hash = "sha256:2c721f11869baac1884e846232800fe021c33f1b4acb3929cff321f7ea4e2982", size = 5624004, upload-time = "2025-06-11T08:48:33.998Z" }, 481 | ] 482 | 483 | [package.optional-dependencies] 484 | nodejs = [ 485 | { name = "nodejs-wheel-binaries" }, 486 | ] 487 | 488 | [[package]] 489 | name = "pytest" 490 | version = "8.4.0" 491 | source = { registry = "https://pypi.org/simple" } 492 | dependencies = [ 493 | { name = "colorama", marker = "sys_platform == 'win32'" }, 494 | { name = "iniconfig" }, 495 | { name = "packaging" }, 496 | { name = "pluggy" }, 497 | { name = "pygments" }, 498 | ] 499 | sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } 500 | wheels = [ 501 | { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, 502 | ] 503 | 504 | [[package]] 505 | name = "python-dateutil" 506 | version = "2.9.0.post0" 507 | source = { registry = "https://pypi.org/simple" } 508 | dependencies = [ 509 | { name = "six" }, 510 | ] 511 | sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } 512 | wheels = [ 513 | { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, 514 | ] 515 | 516 | [[package]] 517 | name = "pywin32" 518 | version = "310" 519 | source = { registry = "https://pypi.org/simple" } 520 | wheels = [ 521 | { url = "https://files.pythonhosted.org/packages/6b/ec/4fdbe47932f671d6e348474ea35ed94227fb5df56a7c30cbbb42cd396ed0/pywin32-310-cp312-cp312-win32.whl", hash = "sha256:8a75a5cc3893e83a108c05d82198880704c44bbaee4d06e442e471d3c9ea4f3d", size = 8796239, upload-time = "2025-03-17T00:55:58.807Z" }, 522 | { url = "https://files.pythonhosted.org/packages/e3/e5/b0627f8bb84e06991bea89ad8153a9e50ace40b2e1195d68e9dff6b03d0f/pywin32-310-cp312-cp312-win_amd64.whl", hash = "sha256:bf5c397c9a9a19a6f62f3fb821fbf36cac08f03770056711f765ec1503972060", size = 9503839, upload-time = "2025-03-17T00:56:00.8Z" }, 523 | { url = "https://files.pythonhosted.org/packages/1f/32/9ccf53748df72301a89713936645a664ec001abd35ecc8578beda593d37d/pywin32-310-cp312-cp312-win_arm64.whl", hash = "sha256:2349cc906eae872d0663d4d6290d13b90621eaf78964bb1578632ff20e152966", size = 8459470, upload-time = "2025-03-17T00:56:02.601Z" }, 524 | { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384, upload-time = "2025-03-17T00:56:04.383Z" }, 525 | { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039, upload-time = "2025-03-17T00:56:06.207Z" }, 526 | { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152, upload-time = "2025-03-17T00:56:07.819Z" }, 527 | ] 528 | 529 | [[package]] 530 | name = "pyzmq" 531 | version = "27.0.0" 532 | source = { registry = "https://pypi.org/simple" } 533 | dependencies = [ 534 | { name = "cffi", marker = "implementation_name == 'pypy'" }, 535 | ] 536 | sdist = { url = "https://files.pythonhosted.org/packages/f1/06/50a4e9648b3e8b992bef8eb632e457307553a89d294103213cfd47b3da69/pyzmq-27.0.0.tar.gz", hash = "sha256:b1f08eeb9ce1510e6939b6e5dcd46a17765e2333daae78ecf4606808442e52cf", size = 280478, upload-time = "2025-06-13T14:09:07.087Z" } 537 | wheels = [ 538 | { url = "https://files.pythonhosted.org/packages/93/a7/9ad68f55b8834ede477842214feba6a4c786d936c022a67625497aacf61d/pyzmq-27.0.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:cbabc59dcfaac66655c040dfcb8118f133fb5dde185e5fc152628354c1598e52", size = 1305438, upload-time = "2025-06-13T14:07:31.676Z" }, 539 | { url = "https://files.pythonhosted.org/packages/ba/ee/26aa0f98665a22bc90ebe12dced1de5f3eaca05363b717f6fb229b3421b3/pyzmq-27.0.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:cb0ac5179cba4b2f94f1aa208fbb77b62c4c9bf24dd446278b8b602cf85fcda3", size = 895095, upload-time = "2025-06-13T14:07:33.104Z" }, 540 | { url = "https://files.pythonhosted.org/packages/cf/85/c57e7ab216ecd8aa4cc7e3b83b06cc4e9cf45c87b0afc095f10cd5ce87c1/pyzmq-27.0.0-cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53a48f0228eab6cbf69fde3aa3c03cbe04e50e623ef92ae395fce47ef8a76152", size = 651826, upload-time = "2025-06-13T14:07:34.831Z" }, 541 | { url = "https://files.pythonhosted.org/packages/69/9a/9ea7e230feda9400fb0ae0d61d7d6ddda635e718d941c44eeab22a179d34/pyzmq-27.0.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:111db5f395e09f7e775f759d598f43cb815fc58e0147623c4816486e1a39dc22", size = 839750, upload-time = "2025-06-13T14:07:36.553Z" }, 542 | { url = "https://files.pythonhosted.org/packages/08/66/4cebfbe71f3dfbd417011daca267539f62ed0fbc68105357b68bbb1a25b7/pyzmq-27.0.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c8878011653dcdc27cc2c57e04ff96f0471e797f5c19ac3d7813a245bcb24371", size = 1641357, upload-time = "2025-06-13T14:07:38.21Z" }, 543 | { url = "https://files.pythonhosted.org/packages/ac/f6/b0f62578c08d2471c791287149cb8c2aaea414ae98c6e995c7dbe008adfb/pyzmq-27.0.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:c0ed2c1f335ba55b5fdc964622254917d6b782311c50e138863eda409fbb3b6d", size = 2020281, upload-time = "2025-06-13T14:07:39.599Z" }, 544 | { url = "https://files.pythonhosted.org/packages/37/b9/4f670b15c7498495da9159edc374ec09c88a86d9cd5a47d892f69df23450/pyzmq-27.0.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e918d70862d4cfd4b1c187310015646a14e1f5917922ab45b29f28f345eeb6be", size = 1877110, upload-time = "2025-06-13T14:07:41.027Z" }, 545 | { url = "https://files.pythonhosted.org/packages/66/31/9dee25c226295b740609f0d46db2fe972b23b6f5cf786360980524a3ba92/pyzmq-27.0.0-cp312-abi3-win32.whl", hash = "sha256:88b4e43cab04c3c0f0d55df3b1eef62df2b629a1a369b5289a58f6fa8b07c4f4", size = 559297, upload-time = "2025-06-13T14:07:42.533Z" }, 546 | { url = "https://files.pythonhosted.org/packages/9b/12/52da5509800f7ff2d287b2f2b4e636e7ea0f001181cba6964ff6c1537778/pyzmq-27.0.0-cp312-abi3-win_amd64.whl", hash = "sha256:dce4199bf5f648a902ce37e7b3afa286f305cd2ef7a8b6ec907470ccb6c8b371", size = 619203, upload-time = "2025-06-13T14:07:43.843Z" }, 547 | { url = "https://files.pythonhosted.org/packages/93/6d/7f2e53b19d1edb1eb4f09ec7c3a1f945ca0aac272099eab757d15699202b/pyzmq-27.0.0-cp312-abi3-win_arm64.whl", hash = "sha256:56e46bbb85d52c1072b3f809cc1ce77251d560bc036d3a312b96db1afe76db2e", size = 551927, upload-time = "2025-06-13T14:07:45.51Z" }, 548 | { url = "https://files.pythonhosted.org/packages/19/62/876b27c4ff777db4ceba1c69ea90d3c825bb4f8d5e7cd987ce5802e33c55/pyzmq-27.0.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:c36ad534c0c29b4afa088dc53543c525b23c0797e01b69fef59b1a9c0e38b688", size = 1340826, upload-time = "2025-06-13T14:07:46.881Z" }, 549 | { url = "https://files.pythonhosted.org/packages/43/69/58ef8f4f59d3bcd505260c73bee87b008850f45edca40ddaba54273c35f4/pyzmq-27.0.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:67855c14173aec36395d7777aaba3cc527b393821f30143fd20b98e1ff31fd38", size = 897283, upload-time = "2025-06-13T14:07:49.562Z" }, 550 | { url = "https://files.pythonhosted.org/packages/43/15/93a0d0396700a60475ad3c5d42c5f1c308d3570bc94626b86c71ef9953e0/pyzmq-27.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8617c7d43cd8ccdb62aebe984bfed77ca8f036e6c3e46dd3dddda64b10f0ab7a", size = 660567, upload-time = "2025-06-13T14:07:51.364Z" }, 551 | { url = "https://files.pythonhosted.org/packages/0e/b3/fe055513e498ca32f64509abae19b9c9eb4d7c829e02bd8997dd51b029eb/pyzmq-27.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:67bfbcbd0a04c575e8103a6061d03e393d9f80ffdb9beb3189261e9e9bc5d5e9", size = 847681, upload-time = "2025-06-13T14:07:52.77Z" }, 552 | { url = "https://files.pythonhosted.org/packages/b6/4f/ff15300b00b5b602191f3df06bbc8dd4164e805fdd65bb77ffbb9c5facdc/pyzmq-27.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5cd11d46d7b7e5958121b3eaf4cd8638eff3a720ec527692132f05a57f14341d", size = 1650148, upload-time = "2025-06-13T14:07:54.178Z" }, 553 | { url = "https://files.pythonhosted.org/packages/c4/6f/84bdfff2a224a6f26a24249a342e5906993c50b0761e311e81b39aef52a7/pyzmq-27.0.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:b801c2e40c5aa6072c2f4876de8dccd100af6d9918d4d0d7aa54a1d982fd4f44", size = 2023768, upload-time = "2025-06-13T14:07:55.714Z" }, 554 | { url = "https://files.pythonhosted.org/packages/64/39/dc2db178c26a42228c5ac94a9cc595030458aa64c8d796a7727947afbf55/pyzmq-27.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:20d5cb29e8c5f76a127c75b6e7a77e846bc4b655c373baa098c26a61b7ecd0ef", size = 1885199, upload-time = "2025-06-13T14:07:57.166Z" }, 555 | { url = "https://files.pythonhosted.org/packages/c7/21/dae7b06a1f8cdee5d8e7a63d99c5d129c401acc40410bef2cbf42025e26f/pyzmq-27.0.0-cp313-cp313t-win32.whl", hash = "sha256:a20528da85c7ac7a19b7384e8c3f8fa707841fd85afc4ed56eda59d93e3d98ad", size = 575439, upload-time = "2025-06-13T14:07:58.959Z" }, 556 | { url = "https://files.pythonhosted.org/packages/eb/bc/1709dc55f0970cf4cb8259e435e6773f9946f41a045c2cb90e870b7072da/pyzmq-27.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d8229f2efece6a660ee211d74d91dbc2a76b95544d46c74c615e491900dc107f", size = 639933, upload-time = "2025-06-13T14:08:00.777Z" }, 557 | ] 558 | 559 | [[package]] 560 | name = "ruff" 561 | version = "0.11.13" 562 | source = { registry = "https://pypi.org/simple" } 563 | sdist = { url = "https://files.pythonhosted.org/packages/ed/da/9c6f995903b4d9474b39da91d2d626659af3ff1eeb43e9ae7c119349dba6/ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514", size = 4282054, upload-time = "2025-06-05T21:00:15.721Z" } 564 | wheels = [ 565 | { url = "https://files.pythonhosted.org/packages/7d/ce/a11d381192966e0b4290842cc8d4fac7dc9214ddf627c11c1afff87da29b/ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46", size = 10292516, upload-time = "2025-06-05T20:59:32.944Z" }, 566 | { url = "https://files.pythonhosted.org/packages/78/db/87c3b59b0d4e753e40b6a3b4a2642dfd1dcaefbff121ddc64d6c8b47ba00/ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48", size = 11106083, upload-time = "2025-06-05T20:59:37.03Z" }, 567 | { url = "https://files.pythonhosted.org/packages/77/79/d8cec175856ff810a19825d09ce700265f905c643c69f45d2b737e4a470a/ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b", size = 10436024, upload-time = "2025-06-05T20:59:39.741Z" }, 568 | { url = "https://files.pythonhosted.org/packages/8b/5b/f6d94f2980fa1ee854b41568368a2e1252681b9238ab2895e133d303538f/ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a", size = 10646324, upload-time = "2025-06-05T20:59:42.185Z" }, 569 | { url = "https://files.pythonhosted.org/packages/6c/9c/b4c2acf24ea4426016d511dfdc787f4ce1ceb835f3c5fbdbcb32b1c63bda/ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc", size = 10174416, upload-time = "2025-06-05T20:59:44.319Z" }, 570 | { url = "https://files.pythonhosted.org/packages/f3/10/e2e62f77c65ede8cd032c2ca39c41f48feabedb6e282bfd6073d81bb671d/ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629", size = 11724197, upload-time = "2025-06-05T20:59:46.935Z" }, 571 | { url = "https://files.pythonhosted.org/packages/bb/f0/466fe8469b85c561e081d798c45f8a1d21e0b4a5ef795a1d7f1a9a9ec182/ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933", size = 12511615, upload-time = "2025-06-05T20:59:49.534Z" }, 572 | { url = "https://files.pythonhosted.org/packages/17/0e/cefe778b46dbd0cbcb03a839946c8f80a06f7968eb298aa4d1a4293f3448/ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165", size = 12117080, upload-time = "2025-06-05T20:59:51.654Z" }, 573 | { url = "https://files.pythonhosted.org/packages/5d/2c/caaeda564cbe103bed145ea557cb86795b18651b0f6b3ff6a10e84e5a33f/ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71", size = 11326315, upload-time = "2025-06-05T20:59:54.469Z" }, 574 | { url = "https://files.pythonhosted.org/packages/75/f0/782e7d681d660eda8c536962920c41309e6dd4ebcea9a2714ed5127d44bd/ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9", size = 11555640, upload-time = "2025-06-05T20:59:56.986Z" }, 575 | { url = "https://files.pythonhosted.org/packages/5d/d4/3d580c616316c7f07fb3c99dbecfe01fbaea7b6fd9a82b801e72e5de742a/ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc", size = 10507364, upload-time = "2025-06-05T20:59:59.154Z" }, 576 | { url = "https://files.pythonhosted.org/packages/5a/dc/195e6f17d7b3ea6b12dc4f3e9de575db7983db187c378d44606e5d503319/ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7", size = 10141462, upload-time = "2025-06-05T21:00:01.481Z" }, 577 | { url = "https://files.pythonhosted.org/packages/f4/8e/39a094af6967faa57ecdeacb91bedfb232474ff8c3d20f16a5514e6b3534/ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432", size = 11121028, upload-time = "2025-06-05T21:00:04.06Z" }, 578 | { url = "https://files.pythonhosted.org/packages/5a/c0/b0b508193b0e8a1654ec683ebab18d309861f8bd64e3a2f9648b80d392cb/ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492", size = 11602992, upload-time = "2025-06-05T21:00:06.249Z" }, 579 | { url = "https://files.pythonhosted.org/packages/7c/91/263e33ab93ab09ca06ce4f8f8547a858cc198072f873ebc9be7466790bae/ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250", size = 10474944, upload-time = "2025-06-05T21:00:08.459Z" }, 580 | { url = "https://files.pythonhosted.org/packages/46/f4/7c27734ac2073aae8efb0119cae6931b6fb48017adf048fdf85c19337afc/ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3", size = 11548669, upload-time = "2025-06-05T21:00:11.147Z" }, 581 | { url = "https://files.pythonhosted.org/packages/ec/bf/b273dd11673fed8a6bd46032c0ea2a04b2ac9bfa9c628756a5856ba113b0/ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b", size = 10683928, upload-time = "2025-06-05T21:00:13.758Z" }, 582 | ] 583 | 584 | [[package]] 585 | name = "six" 586 | version = "1.17.0" 587 | source = { registry = "https://pypi.org/simple" } 588 | sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } 589 | wheels = [ 590 | { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, 591 | ] 592 | 593 | [[package]] 594 | name = "stack-data" 595 | version = "0.6.3" 596 | source = { registry = "https://pypi.org/simple" } 597 | dependencies = [ 598 | { name = "asttokens" }, 599 | { name = "executing" }, 600 | { name = "pure-eval" }, 601 | ] 602 | sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } 603 | wheels = [ 604 | { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, 605 | ] 606 | 607 | [[package]] 608 | name = "tornado" 609 | version = "6.5.1" 610 | source = { registry = "https://pypi.org/simple" } 611 | sdist = { url = "https://files.pythonhosted.org/packages/51/89/c72771c81d25d53fe33e3dca61c233b665b2780f21820ba6fd2c6793c12b/tornado-6.5.1.tar.gz", hash = "sha256:84ceece391e8eb9b2b95578db65e920d2a61070260594819589609ba9bc6308c", size = 509934, upload-time = "2025-05-22T18:15:38.788Z" } 612 | wheels = [ 613 | { url = "https://files.pythonhosted.org/packages/77/89/f4532dee6843c9e0ebc4e28d4be04c67f54f60813e4bf73d595fe7567452/tornado-6.5.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d50065ba7fd11d3bd41bcad0825227cc9a95154bad83239357094c36708001f7", size = 441948, upload-time = "2025-05-22T18:15:20.862Z" }, 614 | { url = "https://files.pythonhosted.org/packages/15/9a/557406b62cffa395d18772e0cdcf03bed2fff03b374677348eef9f6a3792/tornado-6.5.1-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9e9ca370f717997cb85606d074b0e5b247282cf5e2e1611568b8821afe0342d6", size = 440112, upload-time = "2025-05-22T18:15:22.591Z" }, 615 | { url = "https://files.pythonhosted.org/packages/55/82/7721b7319013a3cf881f4dffa4f60ceff07b31b394e459984e7a36dc99ec/tornado-6.5.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b77e9dfa7ed69754a54c89d82ef746398be82f749df69c4d3abe75c4d1ff4888", size = 443672, upload-time = "2025-05-22T18:15:24.027Z" }, 616 | { url = "https://files.pythonhosted.org/packages/7d/42/d11c4376e7d101171b94e03cef0cbce43e823ed6567ceda571f54cf6e3ce/tornado-6.5.1-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253b76040ee3bab8bcf7ba9feb136436a3787208717a1fb9f2c16b744fba7331", size = 443019, upload-time = "2025-05-22T18:15:25.735Z" }, 617 | { url = "https://files.pythonhosted.org/packages/7d/f7/0c48ba992d875521ac761e6e04b0a1750f8150ae42ea26df1852d6a98942/tornado-6.5.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:308473f4cc5a76227157cdf904de33ac268af770b2c5f05ca6c1161d82fdd95e", size = 443252, upload-time = "2025-05-22T18:15:27.499Z" }, 618 | { url = "https://files.pythonhosted.org/packages/89/46/d8d7413d11987e316df4ad42e16023cd62666a3c0dfa1518ffa30b8df06c/tornado-6.5.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:caec6314ce8a81cf69bd89909f4b633b9f523834dc1a352021775d45e51d9401", size = 443930, upload-time = "2025-05-22T18:15:29.299Z" }, 619 | { url = "https://files.pythonhosted.org/packages/78/b2/f8049221c96a06df89bed68260e8ca94beca5ea532ffc63b1175ad31f9cc/tornado-6.5.1-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:13ce6e3396c24e2808774741331638ee6c2f50b114b97a55c5b442df65fd9692", size = 443351, upload-time = "2025-05-22T18:15:31.038Z" }, 620 | { url = "https://files.pythonhosted.org/packages/76/ff/6a0079e65b326cc222a54720a748e04a4db246870c4da54ece4577bfa702/tornado-6.5.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5cae6145f4cdf5ab24744526cc0f55a17d76f02c98f4cff9daa08ae9a217448a", size = 443328, upload-time = "2025-05-22T18:15:32.426Z" }, 621 | { url = "https://files.pythonhosted.org/packages/49/18/e3f902a1d21f14035b5bc6246a8c0f51e0eef562ace3a2cea403c1fb7021/tornado-6.5.1-cp39-abi3-win32.whl", hash = "sha256:e0a36e1bc684dca10b1aa75a31df8bdfed656831489bc1e6a6ebed05dc1ec365", size = 444396, upload-time = "2025-05-22T18:15:34.205Z" }, 622 | { url = "https://files.pythonhosted.org/packages/7b/09/6526e32bf1049ee7de3bebba81572673b19a2a8541f795d887e92af1a8bc/tornado-6.5.1-cp39-abi3-win_amd64.whl", hash = "sha256:908e7d64567cecd4c2b458075589a775063453aeb1d2a1853eedb806922f568b", size = 444840, upload-time = "2025-05-22T18:15:36.1Z" }, 623 | { url = "https://files.pythonhosted.org/packages/55/a7/535c44c7bea4578e48281d83c615219f3ab19e6abc67625ef637c73987be/tornado-6.5.1-cp39-abi3-win_arm64.whl", hash = "sha256:02420a0eb7bf617257b9935e2b754d1b63897525d8a289c9d65690d580b4dcf7", size = 443596, upload-time = "2025-05-22T18:15:37.433Z" }, 624 | ] 625 | 626 | [[package]] 627 | name = "traitlets" 628 | version = "5.14.3" 629 | source = { registry = "https://pypi.org/simple" } 630 | sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } 631 | wheels = [ 632 | { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, 633 | ] 634 | 635 | [[package]] 636 | name = "typing-extensions" 637 | version = "4.14.0" 638 | source = { registry = "https://pypi.org/simple" } 639 | sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } 640 | wheels = [ 641 | { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, 642 | ] 643 | 644 | [[package]] 645 | name = "wcwidth" 646 | version = "0.2.13" 647 | source = { registry = "https://pypi.org/simple" } 648 | sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } 649 | wheels = [ 650 | { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, 651 | ] 652 | --------------------------------------------------------------------------------