diff --git a/.env.example b/.env.example
index f6a88375f..cec7b1d2f 100644
--- a/.env.example
+++ b/.env.example
@@ -1,5 +1,7 @@
-FORK_URL=
NODE_ENV=
+FORK_URL=
DEV_RPC=
+
+# TODO: determine if these are needed
STAKING_TEST_KEYS_PATH=
IS_STAGING=
diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml
index 24a790c4a..f2655da3c 100644
--- a/.github/workflows/backend.yml
+++ b/.github/workflows/backend.yml
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
# Node.js (for package scripts)
- uses: actions/setup-node@v4
diff --git a/.github/workflows/common_checks.yml b/.github/workflows/common_checks.yml
index f4258a3d2..df38258ba 100644
--- a/.github/workflows/common_checks.yml
+++ b/.github/workflows/common_checks.yml
@@ -15,7 +15,7 @@ jobs:
python-version: ["3.10.9"]
timeout-minutes: 30
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- uses: actions/setup-python@master
with:
python-version: ${{ matrix.python-version }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a07e5fe40..9ba0fd8c5 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -54,7 +54,7 @@ jobs:
poetry run pyinstaller --collect-data eth_account --collect-all aea --collect-all autonomy --collect-all operate --collect-all aea_ledger_ethereum --collect-all aea_ledger_cosmos --collect-all aea_ledger_ethereum_flashbots --hidden-import aea_ledger_ethereum --hidden-import aea_ledger_cosmos --hidden-import aea_ledger_ethereum_flashbots operate/pearl.py --add-binary dist/aea_bin:. --add-binary dist/tendermint:. --onefile --name pearl_${{ env.OS_ARCH }}
- name: Upload Release Assets
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: pearl_${{ env.OS_ARCH }}
path: dist/pearl_${{ env.OS_ARCH }}
@@ -64,7 +64,7 @@ jobs:
needs:
- "build-macos-pyinstaller"
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.10"
@@ -72,12 +72,12 @@ jobs:
with:
node-version: lts/*
- name: Download artifacts
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
with:
name: pearl_x64
path: electron/bins/
- name: Download artifacts
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
with:
name: pearl_arm64
path: electron/bins/
diff --git a/.github/workflows/release_win.yml b/.github/workflows/release_win.yml
new file mode 100644
index 000000000..4a3d3efeb
--- /dev/null
+++ b/.github/workflows/release_win.yml
@@ -0,0 +1,55 @@
+name: Release for Windows
+
+on:
+ push:
+ tags:
+ - 'v*.*.*'
+
+jobs:
+ build-windows:
+ runs-on: windows-latest
+ defaults:
+ run:
+ shell: bash
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: lts/*
+
+ - name: Install and configure Poetry
+ uses: snok/install-poetry@v1
+ with:
+ version: '1.8.3'
+ virtualenvs-create: true
+ virtualenvs-in-project: false
+ virtualenvs-path: ~/my-custom-path
+ installer-parallel: true
+ - name: Install dependencies
+ run: poetry install
+
+ - name: install node deps
+ run: yarn install-deps
+
+ - name: set env vars to prod.env
+ env:
+ NODE_ENV: production
+ DEV_RPC: https://rpc-gate.autonolas.tech/gnosis-rpc/
+ IS_STAGING: ${{ github.ref != 'refs/heads/main' && 'true' || 'false' }}
+ FORK_URL: https://rpc-gate.autonolas.tech/gnosis-rpc/
+ GH_TOKEN: ${{ secrets.github_token}}
+ run: |
+ echo NODE_ENV=$NODE_ENV >> prod.env
+ echo DEV_RPC=$DEV_RPC >> prod.env
+ echo IS_STAGING=$IS_STAGING >> prod.env
+ echo FORK_URL=$FORK_URL >> prod.env
+ cat prod.env
+ echo GH_TOKEN=$GH_TOKEN >> prod.env
+ - run: rm -rf /dist
+ - name: "Build, notarize, publish"
+ run: make build
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..5a766bb51
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,58 @@
+
+define setup_env
+ $(eval ENV_FILE := $(1).env)
+ @echo " - setup env $(ENV_FILE)"
+ $(eval include $(1).env)
+ $(eval export)
+endef
+
+
+./trader/:
+ pwd
+ git clone https://github.com/valory-xyz/trader.git
+
+./dist/aea_win.exe: ./trader/
+ mkdir -p dist
+ cd trader && poetry install && poetry run pyinstaller --collect-data eth_account --collect-all aea --collect-all autonomy --collect-all operate --collect-all aea_ledger_ethereum --collect-all aea_ledger_cosmos --collect-all aea_ledger_ethereum_flashbots --hidden-import aea_ledger_ethereum --hidden-import aea_ledger_cosmos --hidden-import aea_ledger_ethereum_flashbots --hidden-import grpc --hidden-import openapi_core --collect-all google.protobuf --collect-all openapi_core --collect-all openapi_spec_validator --collect-all asn1crypto --hidden-import py_ecc --hidden-import pytz --onefile pyinstaller/trader_bin.py --name trader_win
+ cp -f trader/dist/trader_win.exe ./dist/aea_win.exe
+ pwd
+
+
+./dist/tendermint_win.exe: ./operate/
+ pwd
+ poetry install && poetry run pyinstaller operate/services/utils/tendermint.py --onefile --name tendermint_win
+
+
+./dist/pearl_win.exe: ./operate/ ./dist/aea_win.exe ./dist/tendermint_win.exe
+ pwd
+ poetry install && poetry run pyinstaller --collect-data eth_account --collect-all aea --collect-all coincurve --collect-all autonomy --collect-all operate --collect-all aea_ledger_ethereum --collect-all aea_ledger_cosmos --collect-all aea_ledger_ethereum_flashbots --hidden-import aea_ledger_ethereum --hidden-import aea_ledger_cosmos --hidden-import aea_ledger_ethereum_flashbots operate/pearl.py --add-binary dist/aea_win.exe:. --add-binary dist/tendermint_win.exe:. --onefile --name pearl_win
+
+
+./electron/bins/:
+ mkdir -p ./electron/bins/
+
+./electron/bins/tendermint.exe: ./electron/bins/
+ curl -L https://github.com/tendermint/tendermint/releases/download/v0.34.19/tendermint_0.34.19_windows_amd64.tar.gz -o tendermint.tar.gz
+ tar -xvf tendermint.tar.gz tendermint.exe
+ cp ./tendermint.exe ./electron/bins/tendermint.exe
+
+.PHONY: build
+build: ./dist/pearl_win.exe ./electron/bins/tendermint.exe
+ $(call setup_env, prod)
+ echo ${DEV_RPC}
+ cp -f dist/pearl_win.exe ./electron/bins/pearl_win.exe
+ echo ${NODE_ENV}
+ NODE_ENV=${NODE_ENV} DEV_RPC=${DEV_RPC} FORK_URL=${FORK_URL} yarn build:frontend
+ NODE_ENV=${NODE_ENV} DEV_RPC=${DEV_RPC} FORK_URL=${FORK_URL} GH_TOKEN=${GH_TOKEN} node build-win.js
+
+
+
+
+.PHONY: build-tenderly
+build-tenderly: ./dist/pearl_win.exe
+ $(call setup_env, dev-tenderly)
+ echo ${DEV_RPC}
+ cp -f dist/pearl_win.exe ./electron/bins/pearl_win.exe
+ echo ${NODE_ENV}
+ NODE_ENV=${NODE_ENV} DEV_RPC=${DEV_RPC} FORK_URL=${FORK_URL} yarn build:frontend
+ GH_TOKEN=${GH_TOKEN} node build-win-tenderly.js
\ No newline at end of file
diff --git a/build-win-tenderly.js b/build-win-tenderly.js
new file mode 100644
index 000000000..68fbdbbf4
--- /dev/null
+++ b/build-win-tenderly.js
@@ -0,0 +1,38 @@
+/**
+ * This script is used to build the electron app **with notarization**. It is used for the final build and release process.
+ */
+require('dotenv').config();
+const build = require('electron-builder').build;
+
+const { publishOptions } = require('./electron/constants');
+
+const main = async () => {
+ console.log('Building...');
+
+ /** @type import {CliOptions} from "electron-builder" */
+ await build({
+ publish: 'onTag',
+ config: {
+ appId: 'xyz.valory.olas-operate-app',
+ artifactName: '${productName}-${version}-${platform}-${arch}-tenderly.${ext}',
+ productName: 'Pearl',
+ files: ['electron/**/*', 'package.json'],
+ directories: {
+ output: 'dist',
+ },
+ nsis: {
+ oneClick: false,
+ },
+ extraResources: [
+ {
+ from: 'electron/bins',
+ to: 'bins',
+ filter: ['**/*'],
+ },
+ ],
+
+ },
+ });
+};
+
+main().then((response) => { console.log('Build & Notarize complete'); }).catch((e) => console.error(e));
diff --git a/build-win.js b/build-win.js
new file mode 100644
index 000000000..9427337c1
--- /dev/null
+++ b/build-win.js
@@ -0,0 +1,49 @@
+/**
+ * This script is used to build the electron app **with notarization**. It is used for the final build and release process.
+ */
+require('dotenv').config();
+const build = require('electron-builder').build;
+
+const { publishOptions } = require('./electron/constants');
+
+
+function artifactName() {
+ const env = process.env.NODE_ENV;
+ const prefix = env === 'production' ? '' : 'dev-';
+ return prefix + '${productName}-${version}-${platform}-${arch}.${ext}';
+}
+
+const main = async () => {
+ console.log('Building...');
+
+ /** @type import {CliOptions} from "electron-builder" */
+ await build({
+ publish: 'onTag',
+ config: {
+ appId: 'xyz.valory.olas-operate-app',
+ artifactName: artifactName(),
+ productName: 'Pearl',
+ files: ['electron/**/*', 'package.json'],
+ directories: {
+ output: 'dist',
+ },
+ nsis: {
+ oneClick: false,
+ },
+ win: {
+ publish: publishOptions,
+ icon: 'electron/assets/icons/splash-robot-head-dock.png',
+ },
+ extraResources: [
+ {
+ from: 'electron/bins',
+ to: 'bins',
+ filter: ['**/*'],
+ },
+ ],
+
+ },
+ });
+};
+
+main().then((response) => { console.log('Build & Notarize complete'); }).catch((e) => console.error(e));
diff --git a/electron/install.js b/electron/install.js
index 861bf44ed..a117a78b3 100644
--- a/electron/install.js
+++ b/electron/install.js
@@ -6,15 +6,15 @@ const process = require('process');
const axios = require('axios');
const { spawnSync } = require('child_process');
const { logger } = require('./logger');
-
+const { execSync} = require('child_process');
const { paths } = require('./constants');
-
+const homedir = os.homedir();
/**
* current version of the pearl release
* - use "" (nothing as a suffix) for latest release candidate, for example "0.1.0rc26"
* - use "alpha" for alpha release, for example "0.1.0rc26-alpha"
*/
-const OlasMiddlewareVersion = '0.1.0rc120';
+const OlasMiddlewareVersion = '0.1.0rc127';
const path = require('path');
const { app } = require('electron');
@@ -55,6 +55,21 @@ const TendermintUrls = {
},
};
+
+function execSyncExitCode(cmd) {
+ try {
+ execSync(cmd);
+ return 0;
+ }
+ catch (error) {
+ logger.electron(error.status); // Might be 127 in your example.
+ logger.electron(error.message); // Holds the message you typically want.
+ logger.electron(error.stderr.toString()); // Holds the stderr output. Use `.toString()`.
+ logger.electron(error.stdout.toString()); // Holds the stdout output. Use `.toString()`.
+ return error.status;
+ }
+}
+
function getBinPath(command) {
return spawnSync('/usr/bin/which', [command], { env: Env })
.stdout?.toString()
@@ -79,6 +94,7 @@ function runCmdUnix(command, options) {
logger.electron(`===== stderr ===== \n${output.stderr}`);
}
+
function runSudoUnix(command, options) {
let bin = getBinPath(command);
if (!bin) {
@@ -113,6 +129,12 @@ function isTendermintInstalledUnix() {
return Boolean(getBinPath('tendermint'));
}
+function isTendermintInstalledWindows() {
+ return true;
+ //always installed cause bundled in
+ return execSyncExitCode('tendermint --help') === 0;
+}
+
async function downloadFile(url, dest) {
const writer = fs.createWriteStream(dest);
try {
@@ -132,6 +154,41 @@ async function downloadFile(url, dest) {
}
}
+async function installTendermintWindows() {
+ return;
+ // bundled in
+ logger.electron(`Installing tendermint for ${os.platform()}-${process.arch}`);
+ const cwd = process.cwd();
+ process.chdir(paths.tempDir);
+
+ const url = TendermintUrls[os.platform()][process.arch];
+
+ logger.electron(
+ `Downloading ${url} to ${paths.tempDir}. This might take a while...`,
+ );
+ await downloadFile(url, `${paths.tempDir}/tendermint.tar.gz`);
+
+ logger.electron(`Installing tendermint binary`);
+ try {
+ execSync('tar -xvf tendermint.tar.gz');
+ } catch (error){
+ logger.electron(error.status); // Might be 127 in your example.
+ logger.electron(error.message); // Holds the message you typically want.
+ logger.electron(error.stderr.toString()); // Holds the stderr output. Use `.toString()`.
+ logger.electron(error.stdout.toString()); // Holds the stdout output. Use `.toString()`.
+ }
+
+ const bin_dir = homedir + "//AppData//Local//Microsoft//WindowsApps//"
+ if (!Env.CI) {
+ if (!fs.existsSync(bin_dir)) {
+ fs.mkdirSync(bin_dir, {recursive: true});
+ }
+ fs.copyFileSync("tendermint.exe", bin_dir + "tendermint.exe");
+ }
+ process.chdir(cwd);
+}
+
+
async function installTendermintUnix() {
logger.electron(`Installing tendermint for ${os.platform()}-${process.arch}`);
const cwd = process.cwd();
@@ -202,8 +259,24 @@ async function setupUbuntu(ipcChannel) {
}
}
+
+
+async function setupWindows(ipcChannel) {
+ logger.electron('Creating required directories');
+ await createDirectory(`${paths.dotOperateDirectory}`);
+ await createDirectory(`${paths.tempDir}`);
+
+ logger.electron('Checking tendermint installation: ' + isTendermintInstalledWindows());
+ if (!isTendermintInstalledWindows()) {
+ ipcChannel.send('response', 'Installing tendermint');
+ logger.electron('Installing tendermint');
+ await installTendermintWindows();
+ }
+}
+
module.exports = {
setupDarwin,
setupUbuntu,
+ setupWindows,
Env,
};
diff --git a/electron/main.js b/electron/main.js
index e60d56fd1..5216987e2 100644
--- a/electron/main.js
+++ b/electron/main.js
@@ -17,7 +17,7 @@ const http = require('http');
const AdmZip = require('adm-zip');
const { TRAY_ICONS, TRAY_ICONS_PATHS } = require('./icons');
-const { setupDarwin, setupUbuntu, Env } = require('./install');
+const { setupDarwin, setupUbuntu, setupWindows, Env } = require('./install');
const { paths } = require('./constants');
const { killProcesses } = require('./processes');
@@ -39,6 +39,9 @@ const binaryPaths = {
arm64: 'bins/pearl_arm64',
x64: 'bins/pearl_x64',
},
+ win32: {
+ x64: 'bins/pearl_win.exe',
+ },
};
let appConfig = {
@@ -54,8 +57,12 @@ let appConfig = {
},
};
+/**
+ * @type {BrowserWindow}
+ */
+let mainWindow;
+
let tray,
- mainWindow,
splashWindow,
operateDaemon,
operateDaemonPid,
@@ -240,6 +247,14 @@ const createMainWindow = async () => {
showNotification(title, description || undefined);
});
+ // if app (ie. mainWindow) is loaded, destroy splash window.
+ ipcMain.on('is-app-loaded', (_event, isLoaded) => {
+ if (isLoaded && splashWindow) {
+ splashWindow.destroy();
+ splashWindow = null;
+ }
+ });
+
mainWindow.webContents.on('did-fail-load', () => {
mainWindow.webContents.reloadIgnoringCache();
});
@@ -258,7 +273,7 @@ const createMainWindow = async () => {
event.preventDefault();
mainWindow.hide();
});
-
+
try {
logger.electron('Setting up store IPC');
await setupStoreIpc(ipcMain, mainWindow);
@@ -398,6 +413,7 @@ async function launchNextAppDev() {
'yarn',
['dev:frontend', '--port', appConfig.ports.dev.next],
{
+ shell: true,
env: {
...process.env,
NEXT_PUBLIC_BACKEND_PORT: appConfig.ports.dev.operate,
@@ -441,7 +457,7 @@ ipcMain.on('check', async function (event, _argument) {
if (platform === 'darwin') {
await setupDarwin(event.sender);
} else if (platform === 'win32') {
- // TODO
+ await setupWindows(event.sender);
} else {
await setupUbuntu(event.sender);
}
@@ -498,7 +514,6 @@ ipcMain.on('check', async function (event, _argument) {
event.sender.send('response', 'Launching App');
await createMainWindow();
createTray();
- splashWindow.destroy();
} catch (e) {
logger.electron(e);
new Notification({
@@ -517,6 +532,7 @@ app.on('ready', async () => {
path.join(__dirname, 'assets/icons/splash-robot-head-dock.png'),
);
}
+
createSplashWindow();
});
diff --git a/electron/preload.js b/electron/preload.js
index 2878e232e..562f49c72 100644
--- a/electron/preload.js
+++ b/electron/preload.js
@@ -1,6 +1,8 @@
const { contextBridge, ipcRenderer } = require('electron/renderer');
contextBridge.exposeInMainWorld('electronAPI', {
+ setIsAppLoaded: (isAppLoaded) =>
+ ipcRenderer.send('is-app-loaded', isAppLoaded),
closeApp: () => ipcRenderer.send('close-app'),
minimizeApp: () => ipcRenderer.send('minimize-app'),
setTrayIcon: (status) => ipcRenderer.send('tray', status),
diff --git a/electron/processes.js b/electron/processes.js
index e67dcaac5..faaa9266f 100644
--- a/electron/processes.js
+++ b/electron/processes.js
@@ -3,7 +3,7 @@ const { exec } = require('child_process');
const unixKillCommand = 'kill -9';
const windowsKillCommand = 'taskkill /F /PID';
-
+const { logger } = require('./logger');
const isWindows = process.platform === 'win32';
function killProcesses(pid) {
@@ -16,23 +16,29 @@ function killProcesses(pid) {
// Array of PIDs to kill, starting with the children
const pidsToKill = children.map((p) => p.PID);
- pidsToKill.push(pid); // Also kill the main process
+ logger.info("Pids to kill " + JSON.stringify(pidsToKill));
const killCommand = isWindows ? windowsKillCommand : unixKillCommand;
- const joinedCommand = pidsToKill
- .map((pid) => `${killCommand} ${pid}`)
- .join('; '); // Separate commands with a semicolon, so they run in sequence even if one fails. Also works on Windows.
-
- exec(joinedCommand, (err) => {
- if (
- err?.message?.includes(isWindows ? 'not found' : 'No such process')
- ) {
- return; // Ignore errors for processes that are already dead
- }
- reject(err);
- });
- resolve();
+ let errors = [];
+ for (const ppid of pidsToKill) {
+ logger.info("kill: " + ppid);
+ exec(`${killCommand} ${ppid}`, (err) => {
+ logger.error("Pids to kill error:" + err);
+ if (
+ err?.message?.includes(isWindows ? 'not found' : 'No such process')
+ ) {
+ return; // Ignore errors for processes that are already dead
+ }
+ errors.push(err);
+ });
+ }
+
+ if (errors.length === 0) {
+ reject(errors);
+
+
+ } else resolve();
});
});
}
diff --git a/frontend/client/types.ts b/frontend/client/types.ts
index fc5d7fe72..9b3c25ca7 100644
--- a/frontend/client/types.ts
+++ b/frontend/client/types.ts
@@ -1,4 +1,4 @@
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { Address } from '@/types/Address';
import { Chain, DeploymentStatus, Ledger } from './enums';
@@ -30,7 +30,7 @@ export type ChainData = {
safe: number;
};
nft: string;
- staking_program_id: StakingProgram;
+ staking_program_id: StakingProgramId;
threshold: number;
use_staking: true;
};
@@ -62,7 +62,7 @@ export type ServiceTemplate = {
export type ConfigurationTemplate = {
rpc?: string; // added on deployment
- staking_program_id?: StakingProgram; // added on deployment
+ staking_program_id?: StakingProgramId; // added on deployment
nft: string;
agent_id: number;
threshold: number;
diff --git a/frontend/components/InfoBreakdown.tsx b/frontend/components/InfoBreakdown.tsx
new file mode 100644
index 000000000..6fff80bc0
--- /dev/null
+++ b/frontend/components/InfoBreakdown.tsx
@@ -0,0 +1,63 @@
+import { CSSProperties, ReactNode } from 'react';
+import styled from 'styled-components';
+
+import { COLOR } from '@/constants/colors';
+
+type Size = 'small' | 'default' | 'large';
+type Color = 'default' | 'primary';
+
+const Breakdown = styled.div`
+ display: flex;
+ flex-direction: column;
+`;
+
+const BreakdownLine = styled.div<{ size?: Size }>`
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: ${({ size }: { size?: Size }) => {
+ switch (size) {
+ case 'small':
+ return '14px';
+ case 'large':
+ return '16px';
+ default:
+ return 'inherit';
+ }
+ }};
+ color: ${COLOR.TEXT};
+ width: 100%;
+ gap: 12px;
+`;
+
+const Line = styled.span<{ color?: Color }>`
+ flex: 1;
+ border-top: ${({ color }: { color?: Color }) =>
+ `1px solid ${color === 'primary' ? COLOR.PURPLE_LIGHT : COLOR.BORDER_GRAY}`};
+`;
+
+type Info = { id?: number | string; left: ReactNode; right: ReactNode };
+type InfoBreakdownListProps = {
+ list: Info[];
+ parentStyle?: CSSProperties;
+ size?: Size;
+ color?: Color;
+};
+
+export const InfoBreakdownList = ({
+ list,
+ parentStyle,
+ size,
+ color,
+}: InfoBreakdownListProps) => (
+
+ {list.map((item, index) => (
+
+ {item.left}
+
+ {item.right}
+
+ ))}
+
+);
diff --git a/frontend/components/MainPage/header/AgentButton.tsx b/frontend/components/MainPage/header/AgentButton.tsx
index 6fcdbdea0..06fd81b34 100644
--- a/frontend/components/MainPage/header/AgentButton.tsx
+++ b/frontend/components/MainPage/header/AgentButton.tsx
@@ -4,7 +4,6 @@ import { useCallback, useMemo } from 'react';
import { Chain, DeploymentStatus } from '@/client';
import { COLOR } from '@/constants/colors';
-import { StakingProgram } from '@/enums/StakingProgram';
import { useBalance } from '@/hooks/useBalance';
import { useElectronApi } from '@/hooks/useElectronApi';
import { useServices } from '@/hooks/useServices';
@@ -108,7 +107,8 @@ const AgentNotRunningButton = () => {
} = useBalance();
const { storeState } = useStore();
const { isEligibleForStaking, isAgentEvicted } = useStakingContractInfo();
- const { activeStakingProgram, defaultStakingProgram } = useStakingProgram();
+ const { activeStakingProgramId, defaultStakingProgramId } =
+ useStakingProgram();
// const minStakingDeposit =
// stakingContractInfoRecord?.[activeStakingProgram ?? defaultStakingProgram]
@@ -116,7 +116,7 @@ const AgentNotRunningButton = () => {
const requiredOlas = getMinimumStakedAmountRequired(
serviceTemplate,
- activeStakingProgram ?? defaultStakingProgram,
+ activeStakingProgramId ?? defaultStakingProgramId,
);
const safeOlasBalance = safeBalance?.OLAS;
@@ -155,7 +155,7 @@ const AgentNotRunningButton = () => {
// Then create / deploy the service
try {
await ServicesService.createService({
- stakingProgram: activeStakingProgram ?? defaultStakingProgram, // overwrite with StakingProgram.Alpha to test migration
+ stakingProgramId: activeStakingProgramId ?? defaultStakingProgramId, // overwrite with StakingProgram.Alpha to test migration
serviceTemplate,
deploy: true,
});
@@ -170,18 +170,7 @@ const AgentNotRunningButton = () => {
// Show success notification based on whether there was a service prior to starting
try {
- if (!service) {
- showNotification?.('Your agent is now running!');
- } else {
- const minimumStakedAmountRequired = getMinimumStakedAmountRequired(
- serviceTemplate,
- StakingProgram.Beta, // users should always deploy on Beta if they are yet to start their agent
- );
-
- showNotification?.(
- `Your agent is running and you've staked ${minimumStakedAmountRequired} OLAS!`,
- );
- }
+ showNotification?.(`Your agent is running!`);
} catch (error) {
console.error(error);
showNotification?.('Error while showing "running" notification');
@@ -199,10 +188,9 @@ const AgentNotRunningButton = () => {
setServiceStatus,
masterSafeAddress,
showNotification,
- activeStakingProgram,
- defaultStakingProgram,
+ activeStakingProgramId,
+ defaultStakingProgramId,
serviceTemplate,
- service,
]);
const isDeployable = useMemo(() => {
diff --git a/frontend/components/MainPage/index.tsx b/frontend/components/MainPage/index.tsx
index f97acf159..9fb839e36 100644
--- a/frontend/components/MainPage/index.tsx
+++ b/frontend/components/MainPage/index.tsx
@@ -3,7 +3,7 @@ import { Button, Card, Flex } from 'antd';
import { useEffect } from 'react';
import { Pages } from '@/enums/PageState';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { useBalance } from '@/hooks/useBalance';
import { usePageState } from '@/hooks/usePageState';
import { useServices } from '@/hooks/useServices';
@@ -17,12 +17,13 @@ import { MainNeedsFunds } from './sections/NeedsFundsSection';
import { NewStakingProgramAlertSection } from './sections/NewStakingProgramAlertSection';
import { MainOlasBalance } from './sections/OlasBalanceSection';
import { MainRewards } from './sections/RewardsSection';
+import { StakingContractUpdate } from './sections/StakingContractUpdate';
export const Main = () => {
const { goto } = usePageState();
const { updateServicesState } = useServices();
const { updateBalances, isLoaded, setIsLoaded } = useBalance();
- const { activeStakingProgram: currentStakingProgram } = useStakingProgram();
+ const { activeStakingProgramId: currentStakingProgram } = useStakingProgram();
useEffect(() => {
if (!isLoaded) {
@@ -53,12 +54,13 @@ export const Main = () => {
style={{ borderTopColor: 'transparent' }}
>
- {currentStakingProgram === StakingProgram.Alpha && (
+ {currentStakingProgram === StakingProgramId.Alpha && (
)}
+
diff --git a/frontend/components/MainPage/modals/MigrationModal.tsx b/frontend/components/MainPage/modals/MigrationModal.tsx
index 30b3b2e08..026cbd203 100644
--- a/frontend/components/MainPage/modals/MigrationModal.tsx
+++ b/frontend/components/MainPage/modals/MigrationModal.tsx
@@ -12,15 +12,15 @@ export const MigrationSuccessModal = ({
open: boolean;
onClose: () => void;
}) => {
- const { activeStakingProgram } = useStakingProgram();
+ const { activeStakingProgramId } = useStakingProgram();
// Close modal if no active staking program, migration doesn't apply to non-stakers
- if (!activeStakingProgram) {
+ if (!activeStakingProgramId) {
onClose();
return null;
}
- const activeStakingProgramMeta = STAKING_PROGRAM_META[activeStakingProgram];
+ const activeStakingProgramMeta = STAKING_PROGRAM_META[activeStakingProgramId];
return (
{
]);
const status = useMemo(() => {
+ if (isNil(isLowBalance)) {
+ return { statusName: 'Loading...', StatusComponent: EmptyDot };
+ }
+
if (isLowBalance) {
return { statusName: 'Too low', StatusComponent: EmptyDot };
}
diff --git a/frontend/components/MainPage/sections/NeedsFundsSection.tsx b/frontend/components/MainPage/sections/NeedsFundsSection.tsx
index 08ae82696..71d0604fe 100644
--- a/frontend/components/MainPage/sections/NeedsFundsSection.tsx
+++ b/frontend/components/MainPage/sections/NeedsFundsSection.tsx
@@ -1,16 +1,11 @@
import { Flex, Typography } from 'antd';
-import { formatUnits } from 'ethers/lib/utils';
import { ReactNode, useEffect, useMemo } from 'react';
import styled from 'styled-components';
import { CustomAlert } from '@/components/Alert';
-import { CHAINS } from '@/constants/chains';
import { UNICODE_SYMBOLS } from '@/constants/symbols';
-import { useBalance } from '@/hooks/useBalance';
import { useElectronApi } from '@/hooks/useElectronApi';
-import { useServiceTemplates } from '@/hooks/useServiceTemplates';
-import { useStore } from '@/hooks/useStore';
-import { getMinimumStakedAmountRequired } from '@/utils/service';
+import { useNeedsFunds } from '@/hooks/useNeedsFunds';
import { CardSection } from '../../styled/CardSection';
@@ -24,86 +19,17 @@ const FundingValue = styled.div`
letter-spacing: -0.72px;
`;
-const useNeedsFunds = () => {
- const { getServiceTemplates } = useServiceTemplates();
-
- const serviceTemplate = useMemo(
- () => getServiceTemplates()[0],
- [getServiceTemplates],
- );
-
- const { storeState } = useStore();
- const { safeBalance, totalOlasStakedBalance } = useBalance();
-
- const isInitialFunded = storeState?.isInitialFunded;
-
- const serviceFundRequirements = useMemo(() => {
- const monthlyGasEstimate = Number(
- formatUnits(
- `${serviceTemplate.configurations[CHAINS.GNOSIS.chainId].monthly_gas_estimate}`,
- 18,
- ),
- );
-
- const minimumStakedAmountRequired =
- getMinimumStakedAmountRequired(serviceTemplate);
-
- return {
- eth: monthlyGasEstimate,
- olas: minimumStakedAmountRequired,
- };
- }, [serviceTemplate]);
-
- const hasEnoughEthForInitialFunding = useMemo(
- () => (safeBalance?.ETH || 0) >= (serviceFundRequirements?.eth || 0),
- [serviceFundRequirements?.eth, safeBalance],
- );
-
- const hasEnoughOlasForInitialFunding = useMemo(() => {
- const olasInSafe = safeBalance?.OLAS || 0;
- const olasStakedBySafe = totalOlasStakedBalance || 0;
-
- const olasInSafeAndStaked = olasInSafe + olasStakedBySafe;
-
- return olasInSafeAndStaked >= serviceFundRequirements.olas;
- }, [
- safeBalance?.OLAS,
- totalOlasStakedBalance,
- serviceFundRequirements?.olas,
- ]);
-
- return {
- hasEnoughEthForInitialFunding,
- hasEnoughOlasForInitialFunding,
- serviceFundRequirements,
- isInitialFunded,
- };
-};
-
export const MainNeedsFunds = () => {
- const { isBalanceLoaded } = useBalance();
const {
hasEnoughEthForInitialFunding,
hasEnoughOlasForInitialFunding,
serviceFundRequirements,
isInitialFunded,
+ needsInitialFunding,
} = useNeedsFunds();
const electronApi = useElectronApi();
- const isVisible: boolean = useMemo(() => {
- if (isInitialFunded) return false;
- if (!isBalanceLoaded) return false;
- if (hasEnoughEthForInitialFunding && hasEnoughOlasForInitialFunding)
- return false;
- return true;
- }, [
- hasEnoughEthForInitialFunding,
- hasEnoughOlasForInitialFunding,
- isBalanceLoaded,
- isInitialFunded,
- ]);
-
const message: ReactNode = useMemo(
() => (
@@ -152,7 +78,7 @@ export const MainNeedsFunds = () => {
isInitialFunded,
]);
- if (!isVisible) return null;
+ if (!needsInitialFunding) return null;
return (
diff --git a/frontend/components/MainPage/sections/OlasBalanceSection.tsx b/frontend/components/MainPage/sections/OlasBalanceSection.tsx
index 0c5571da1..8b8dfd9ae 100644
--- a/frontend/components/MainPage/sections/OlasBalanceSection.tsx
+++ b/frontend/components/MainPage/sections/OlasBalanceSection.tsx
@@ -4,7 +4,7 @@ import { useMemo } from 'react';
import styled from 'styled-components';
import { CustomAlert } from '@/components/Alert';
-import { COLOR } from '@/constants/colors';
+import { InfoBreakdownList } from '@/components/InfoBreakdown';
import { UNICODE_SYMBOLS } from '@/constants/symbols';
import { LOW_MASTER_SAFE_BALANCE } from '@/constants/thresholds';
import { useBalance } from '@/hooks/useBalance';
@@ -20,40 +20,7 @@ const Balance = styled.span`
letter-spacing: -2px;
margin-right: 4px;
`;
-const BalanceBreakdown = styled.div`
- padding: 4px;
-`;
-const BalanceBreakdownLine = styled.div`
- position: relative;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- color: ${COLOR.TEXT};
-
- > span {
- background: ${COLOR.WHITE};
- z-index: 1;
- &:first-child {
- padding-right: 6px;
- }
- &:last-child {
- padding-left: 6px;
- }
- }
- &:before {
- content: '';
- position: absolute;
- bottom: 6px;
- width: 100%;
- border-bottom: 2px dotted ${COLOR.BORDER_GRAY};
- }
-
- &:not(:last-child) {
- margin-bottom: 8px;
- }
-`;
const OVERLAY_STYLE = { maxWidth: '300px', width: '300px' };
const CurrentBalance = () => {
@@ -91,14 +58,14 @@ const CurrentBalance = () => {
placement="bottom"
overlayStyle={OVERLAY_STYLE}
title={
-
- {balances.map((item, index) => (
-
- {item.title}
- {item.value} OLAS
-
- ))}
-
+ ({
+ left: item.title,
+ right: `${item.value} OLAS`,
+ }))}
+ size="small"
+ parentStyle={{ padding: 4, gap: 8 }}
+ />
}
>
diff --git a/frontend/components/MainPage/sections/StakingContractUpdate.tsx b/frontend/components/MainPage/sections/StakingContractUpdate.tsx
new file mode 100644
index 000000000..b769c4702
--- /dev/null
+++ b/frontend/components/MainPage/sections/StakingContractUpdate.tsx
@@ -0,0 +1,83 @@
+import { RightOutlined } from '@ant-design/icons';
+import { Button, Flex, Popover, Skeleton, Typography } from 'antd';
+import { useMemo } from 'react';
+
+import { STAKING_PROGRAM_META } from '@/constants/stakingProgramMeta';
+import { Pages } from '@/enums/PageState';
+import { useBalance } from '@/hooks/useBalance';
+import { useNeedsFunds } from '@/hooks/useNeedsFunds';
+import { usePageState } from '@/hooks/usePageState';
+import { useStakingProgram } from '@/hooks/useStakingProgram';
+
+import { CardSection } from '../../styled/CardSection';
+
+const { Text } = Typography;
+
+export const StakingContractUpdate = () => {
+ const { goto } = usePageState();
+ const { isBalanceLoaded, isLowBalance } = useBalance();
+ const { needsInitialFunding } = useNeedsFunds();
+ const {
+ activeStakingProgramMeta,
+ isActiveStakingProgramLoaded,
+ defaultStakingProgramId,
+ } = useStakingProgram();
+
+ const stakingContractName = useMemo(() => {
+ if (activeStakingProgramMeta) return activeStakingProgramMeta.name;
+ return STAKING_PROGRAM_META[defaultStakingProgramId].name;
+ }, [activeStakingProgramMeta, defaultStakingProgramId]);
+
+ const canUpdateStakingContract = useMemo(() => {
+ if (!isBalanceLoaded) return false;
+ if (isLowBalance) return false;
+ if (needsInitialFunding) return false;
+ return true;
+ }, [isBalanceLoaded, isLowBalance, needsInitialFunding]);
+
+ const stakingButton = useMemo(() => {
+ if (!isActiveStakingProgramLoaded) return ;
+ return (
+
+ );
+ }, [
+ goto,
+ isActiveStakingProgramLoaded,
+ stakingContractName,
+ canUpdateStakingContract,
+ ]);
+
+ return (
+
+
+ Staking contract
+
+ {canUpdateStakingContract ? (
+ stakingButton
+ ) : (
+ Fund your agent to manage staking contracts}
+ >
+ {stakingButton}
+
+ )}
+
+
+ );
+};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/CantMigrateAlert.tsx b/frontend/components/ManageStakingPage/StakingContractSection/CantMigrateAlert.tsx
new file mode 100644
index 000000000..52b23737c
--- /dev/null
+++ b/frontend/components/ManageStakingPage/StakingContractSection/CantMigrateAlert.tsx
@@ -0,0 +1,111 @@
+import { Flex, Typography } from 'antd';
+import { isNil } from 'lodash';
+
+import { CustomAlert } from '@/components/Alert';
+import { StakingProgramId } from '@/enums/StakingProgram';
+import { useBalance } from '@/hooks/useBalance';
+import { useServiceTemplates } from '@/hooks/useServiceTemplates';
+import { useStakingContractInfo } from '@/hooks/useStakingContractInfo';
+import { getMinimumStakedAmountRequired } from '@/utils/service';
+
+import { CantMigrateReason } from './useMigrate';
+
+const { Text } = Typography;
+
+type CantMigrateAlertProps = { stakingProgramId: StakingProgramId };
+
+const AlertInsufficientMigrationFunds = ({
+ stakingProgramId,
+}: CantMigrateAlertProps) => {
+ const { serviceTemplate } = useServiceTemplates();
+ const { isServiceStaked } = useStakingContractInfo();
+ const { safeBalance, totalOlasStakedBalance } = useBalance();
+
+ const totalOlasRequiredForStaking = getMinimumStakedAmountRequired(
+ serviceTemplate,
+ stakingProgramId,
+ );
+
+ if (isNil(totalOlasRequiredForStaking)) return null;
+ if (isNil(safeBalance?.OLAS)) return null;
+ if (isNil(totalOlasStakedBalance)) return null;
+
+ const requiredOlasDeposit = isServiceStaked
+ ? totalOlasRequiredForStaking - (totalOlasStakedBalance + safeBalance.OLAS) // when staked
+ : totalOlasRequiredForStaking - safeBalance.OLAS; // when not staked
+
+ return (
+
+
+ An additional {requiredOlasDeposit} OLAS is required to switch
+
+
+ Add {requiredOlasDeposit} OLAS to your account to
+ meet the contract requirements and switch.
+
+
+ }
+ />
+ );
+};
+
+const AlertNoSlots = () => (
+ No slots currently available - try again later.}
+ />
+);
+
+// TODO: uncomment when required
+//
+// const AlertUpdateToMigrate = () => (
+//
+// App update required
+
+// {/*
+// TODO: Define version requirement in some JSON store?
+// How do we access this date on a previous version?
+// */}
+//
+// Update Pearl to the latest version to switch to the staking contract.
+//
+// {/* TODO: trigger update through IPC */}
+//
+// Update Pearl to the latest version {UNICODE_SYMBOLS.EXTERNAL_LINK}
+//
+//
+// }
+// />
+// );
+
+/**
+ * Displays alerts for specific non-migration reasons
+ */
+export const CantMigrateAlert = ({
+ stakingProgramId,
+ cantMigrateReason,
+}: {
+ stakingProgramId: StakingProgramId;
+ cantMigrateReason: CantMigrateReason;
+}) => {
+ if (cantMigrateReason === CantMigrateReason.NoAvailableStakingSlots) {
+ return ;
+ }
+
+ if (cantMigrateReason === CantMigrateReason.InsufficientOlasToMigrate) {
+ return (
+
+ );
+ }
+
+ return null;
+};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/CountdownUntilMigration.tsx b/frontend/components/ManageStakingPage/StakingContractSection/CountdownUntilMigration.tsx
new file mode 100644
index 000000000..d8f71c07a
--- /dev/null
+++ b/frontend/components/ManageStakingPage/StakingContractSection/CountdownUntilMigration.tsx
@@ -0,0 +1,69 @@
+import { Flex, Typography } from 'antd';
+import { isNil } from 'lodash';
+import { useState } from 'react';
+import { useInterval } from 'usehooks-ts';
+
+import { StakingContractInfo } from '@/types/Autonolas';
+
+const { Text } = Typography;
+
+export const CountdownUntilMigration = ({
+ activeStakingContractInfo,
+}: {
+ activeStakingContractInfo: Partial;
+}) => {
+ const [secondsUntilReady, setSecondsUntilMigration] = useState();
+
+ useInterval(() => {
+ if (!activeStakingContractInfo) return;
+
+ const { serviceStakingStartTime, minimumStakingDuration } =
+ activeStakingContractInfo;
+
+ if (isNil(minimumStakingDuration)) return;
+ if (isNil(serviceStakingStartTime)) return;
+
+ const now = Math.round(Date.now() / 1000);
+ const timeSinceLastStaked = now - serviceStakingStartTime;
+
+ const timeUntilMigration = minimumStakingDuration - timeSinceLastStaked;
+
+ if (timeUntilMigration < 0) {
+ setSecondsUntilMigration(0);
+ return;
+ }
+
+ setSecondsUntilMigration(timeUntilMigration);
+ }, 1000);
+
+ const countdownDisplay = isNil(secondsUntilReady)
+ ? 'Loading...'
+ : countdownDisplayFormat(secondsUntilReady);
+
+ return (
+
+ Can't switch because you unstaked too recently.
+ This may be because your agent was suspended.
+ Keep running your agent and you'll be able to switch in
+ {countdownDisplay}
+
+ );
+};
+
+const countdownDisplayFormat = (totalSeconds: number) => {
+ const days = Math.floor(totalSeconds / (24 * 3600));
+ totalSeconds %= 24 * 3600;
+
+ const hours = Math.floor(totalSeconds / 3600);
+ totalSeconds %= 3600;
+
+ const minutes = Math.floor(totalSeconds / 60);
+ const seconds = totalSeconds % 60;
+
+ // Ensure double digits for hours, minutes, and seconds
+ const formattedHours = String(hours).padStart(2, '0');
+ const formattedMinutes = String(minutes).padStart(2, '0');
+ const formattedSeconds = String(seconds).padStart(2, '0');
+ // TODO: update this support plural and singular text
+ return `${days} days ${formattedHours} hours ${formattedMinutes} minutes ${formattedSeconds} seconds`;
+};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/MigrateButton.tsx b/frontend/components/ManageStakingPage/StakingContractSection/MigrateButton.tsx
new file mode 100644
index 000000000..5d1c33473
--- /dev/null
+++ b/frontend/components/ManageStakingPage/StakingContractSection/MigrateButton.tsx
@@ -0,0 +1,90 @@
+import { Button, Popover } from 'antd';
+import { isNil } from 'lodash';
+import { useMemo } from 'react';
+
+import { DeploymentStatus } from '@/client';
+import { Pages } from '@/enums/PageState';
+import { StakingProgramId } from '@/enums/StakingProgram';
+import { useBalance } from '@/hooks/useBalance';
+import { useModals } from '@/hooks/useModals';
+import { usePageState } from '@/hooks/usePageState';
+import { useServices } from '@/hooks/useServices';
+import { useServiceTemplates } from '@/hooks/useServiceTemplates';
+import { useStakingContractInfo } from '@/hooks/useStakingContractInfo';
+import { useStakingProgram } from '@/hooks/useStakingProgram';
+import { ServicesService } from '@/service/Services';
+
+import { CountdownUntilMigration } from './CountdownUntilMigration';
+import { CantMigrateReason, useMigrate } from './useMigrate';
+
+type MigrateButtonProps = {
+ stakingProgramId: StakingProgramId;
+};
+export const MigrateButton = ({ stakingProgramId }: MigrateButtonProps) => {
+ const { goto } = usePageState();
+ const { serviceTemplate } = useServiceTemplates();
+ const { setIsServicePollingPaused, setServiceStatus, updateServiceStatus } =
+ useServices();
+ const { setIsPaused: setIsBalancePollingPaused } = useBalance();
+ const { updateActiveStakingProgramId: updateStakingProgram } =
+ useStakingProgram();
+ const { activeStakingContractInfo } = useStakingContractInfo();
+ const { setMigrationModalOpen } = useModals();
+
+ const { migrateValidation } = useMigrate(stakingProgramId);
+
+ const popoverContent = useMemo(() => {
+ if (migrateValidation.canMigrate) return null;
+
+ if (
+ migrateValidation.reason ===
+ CantMigrateReason.NotStakedForMinimumDuration &&
+ !isNil(activeStakingContractInfo)
+ ) {
+ return (
+
+ );
+ }
+
+ return migrateValidation.reason;
+ }, [activeStakingContractInfo, migrateValidation]);
+
+ return (
+
+
+
+ );
+};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/StakingContractDetails.tsx b/frontend/components/ManageStakingPage/StakingContractSection/StakingContractDetails.tsx
new file mode 100644
index 000000000..6ff75f3ab
--- /dev/null
+++ b/frontend/components/ManageStakingPage/StakingContractSection/StakingContractDetails.tsx
@@ -0,0 +1,58 @@
+import { Alert, Skeleton } from 'antd';
+import { useMemo } from 'react';
+
+import { InfoBreakdownList } from '@/components/InfoBreakdown';
+import { StakingProgramId } from '@/enums/StakingProgram';
+import { useStakingContractInfo } from '@/hooks/useStakingContractInfo';
+
+export const StakingContractDetails = ({
+ stakingProgramId,
+}: {
+ stakingProgramId: StakingProgramId;
+}) => {
+ const { stakingContractInfoRecord } = useStakingContractInfo();
+
+ const balances = useMemo(() => {
+ if (!stakingContractInfoRecord) return null;
+ if (!stakingProgramId) return null;
+ if (!stakingContractInfoRecord?.[stakingProgramId]) return null;
+
+ const details = stakingContractInfoRecord[stakingProgramId];
+ return [
+ {
+ left: 'Rewards per work period',
+ right: `~ ${details.rewardsPerWorkPeriod?.toFixed(2)} OLAS`,
+ },
+ {
+ left: 'Annual percentage Yield (APY)',
+ right: `${details.apy}%`,
+ },
+ {
+ left: 'Required OLAS for staking',
+ right: `${details.olasStakeRequired} OLAS`,
+ },
+ ];
+ }, [stakingContractInfoRecord, stakingProgramId]);
+
+ if (!stakingContractInfoRecord) {
+ return ;
+ }
+
+ if (!balances) {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/StakingContractFundingButton.tsx b/frontend/components/ManageStakingPage/StakingContractSection/StakingContractFundingButton.tsx
new file mode 100644
index 000000000..4a4837a46
--- /dev/null
+++ b/frontend/components/ManageStakingPage/StakingContractSection/StakingContractFundingButton.tsx
@@ -0,0 +1,21 @@
+import { Button } from 'antd';
+import { useState } from 'react';
+
+import { OpenAddFundsSection } from '@/components/MainPage/sections/AddFundsSection';
+
+export const StakingContractFundingButton = () => {
+ const [isFundingSectionOpen, setIsFundingSectionOpen] = useState(false);
+
+ return (
+ <>
+
+ {isFundingSectionOpen && }
+ >
+ );
+};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/StakingContractTag.tsx b/frontend/components/ManageStakingPage/StakingContractSection/StakingContractTag.tsx
index b09c11a05..cd9e525df 100644
--- a/frontend/components/ManageStakingPage/StakingContractSection/StakingContractTag.tsx
+++ b/frontend/components/ManageStakingPage/StakingContractSection/StakingContractTag.tsx
@@ -5,12 +5,10 @@ import { StakingProgramStatus } from '@/enums/StakingProgramStatus';
export const StakingContractTag = ({
status,
}: {
- status?: StakingProgramStatus;
+ status: StakingProgramStatus | null;
}) => {
- if (status === StakingProgramStatus.New) {
- return New;
- } else if (status === StakingProgramStatus.Selected) {
- return Selected;
+ if (status === StakingProgramStatus.Selected) {
+ return Active;
}
return null;
};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/alerts.tsx b/frontend/components/ManageStakingPage/StakingContractSection/alerts.tsx
deleted file mode 100644
index 7df340884..000000000
--- a/frontend/components/ManageStakingPage/StakingContractSection/alerts.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Flex, Typography } from 'antd';
-
-import { CustomAlert } from '@/components/Alert';
-import { UNICODE_SYMBOLS } from '@/constants/symbols';
-
-const { Text } = Typography;
-
-export const AlertInsufficientMigrationFunds = ({
- masterSafeOlasBalance,
- stakedOlasBalance,
- totalOlasRequiredForStaking,
-}: {
- masterSafeOlasBalance: number;
- stakedOlasBalance: number;
- totalOlasRequiredForStaking: number;
-}) => {
- const requiredOlasDeposit =
- totalOlasRequiredForStaking - (stakedOlasBalance + masterSafeOlasBalance);
-
- return (
-
-
- An additional {requiredOlasDeposit} OLAS is required to switch
-
-
- Add {requiredOlasDeposit} OLAS to your account to
- meet the contract requirements and switch.
-
-
- }
- />
- );
-};
-
-export const AlertNoSlots = () => (
- No slots currently available - try again later.}
- />
-);
-
-export const AlertUpdateToMigrate = () => (
-
- App update required
-
- {/*
- TODO: Define version requirement in some JSON store?
- How do we access this date on a previous version?
- */}
-
- Update Pearl to the latest version to switch to the staking contract.
-
- {/* TODO: trigger update through IPC */}
-
- Update Pearl to the latest version {UNICODE_SYMBOLS.EXTERNAL_LINK}
-
-
- }
- />
-);
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/index.tsx b/frontend/components/ManageStakingPage/StakingContractSection/index.tsx
index 1971f8cc8..c0e7aa048 100644
--- a/frontend/components/ManageStakingPage/StakingContractSection/index.tsx
+++ b/frontend/components/ManageStakingPage/StakingContractSection/index.tsx
@@ -1,341 +1,108 @@
-import { Button, Flex, Popover, theme, Typography } from 'antd';
-import { useMemo, useState } from 'react';
+import { Flex, theme, Typography } from 'antd';
+import { useMemo } from 'react';
-import { Chain, DeploymentStatus } from '@/client';
-import { OpenAddFundsSection } from '@/components/MainPage/sections/AddFundsSection';
+import { Chain } from '@/client';
import { CardSection } from '@/components/styled/CardSection';
import { SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES } from '@/constants/contractAddresses';
import { STAKING_PROGRAM_META } from '@/constants/stakingProgramMeta';
import { UNICODE_SYMBOLS } from '@/constants/symbols';
-import { Pages } from '@/enums/PageState';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { StakingProgramStatus } from '@/enums/StakingProgramStatus';
-import { useBalance } from '@/hooks/useBalance';
-import { useModals } from '@/hooks/useModals';
-import { usePageState } from '@/hooks/usePageState';
-import { useServices } from '@/hooks/useServices';
-import { useServiceTemplates } from '@/hooks/useServiceTemplates';
-import { useStakingContractInfo } from '@/hooks/useStakingContractInfo';
import { useStakingProgram } from '@/hooks/useStakingProgram';
-import { ServicesService } from '@/service/Services';
-import { getMinimumStakedAmountRequired } from '@/utils/service';
-import {
- AlertInsufficientMigrationFunds,
- AlertNoSlots,
- AlertUpdateToMigrate,
-} from './alerts';
+import { CantMigrateAlert } from './CantMigrateAlert';
+import { MigrateButton } from './MigrateButton';
+import { StakingContractDetails } from './StakingContractDetails';
+import { StakingContractFundingButton } from './StakingContractFundingButton';
import { StakingContractTag } from './StakingContractTag';
+import { CantMigrateReason, useMigrate } from './useMigrate';
-// const { Text } = Typography;
-
+const { Title } = Typography;
const { useToken } = theme;
-// const CustomDivider = styled(Divider)`
-// flex: auto;
-// width: max-content;
-// min-width: 0;
-// margin: 0;
-// `;
-
-// const ContractParameter = ({
-// label,
-// value,
-// }: {
-// label: string;
-// value: string;
-// }) => (
-//
-// {label}
-//
-// {value}
-//
-// );
-
+type StakingContractSectionProps = { stakingProgramId: StakingProgramId };
export const StakingContractSection = ({
- stakingProgram,
-}: {
- stakingProgram: StakingProgram;
-}) => {
- const { goto } = usePageState();
- const {
- setServiceStatus,
- serviceStatus,
- setIsServicePollingPaused,
- updateServiceStatus,
- } = useServices();
- const { serviceTemplate } = useServiceTemplates();
- const { setMigrationModalOpen } = useModals();
- const { activeStakingProgram, defaultStakingProgram, updateStakingProgram } =
+ stakingProgramId,
+}: StakingContractSectionProps) => {
+ const { activeStakingProgramId, defaultStakingProgramId } =
useStakingProgram();
+
const { token } = useToken();
- const { safeBalance, totalOlasStakedBalance, isBalanceLoaded } = useBalance();
- const { isServiceStakedForMinimumDuration, stakingContractInfoRecord } =
- useStakingContractInfo();
- const [isFundingSectionOpen, setIsFundingSectionOpen] = useState(false);
+
+ const { migrateValidation } = useMigrate(stakingProgramId);
const stakingContractAddress =
SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS][
- stakingProgram
+ stakingProgramId
];
- const stakingContractInfoForStakingProgram =
- stakingContractInfoRecord?.[stakingProgram];
-
- const activeStakingProgramMeta = STAKING_PROGRAM_META[stakingProgram];
-
- const isSelected =
- activeStakingProgram && activeStakingProgram === stakingProgram;
-
- const hasEnoughRewards = true;
- //(stakingContractInfoForStakingProgram?.availableRewards ?? 0) > 0;
-
- const minimumOlasRequiredToMigrate = useMemo(
- () => getMinimumStakedAmountRequired(serviceTemplate, StakingProgram.Beta),
- [serviceTemplate],
- );
-
- const hasEnoughOlasToMigrate = useMemo(() => {
- if (safeBalance?.OLAS === undefined || totalOlasStakedBalance === undefined)
- return false;
-
- const balanceForMigration = safeBalance.OLAS + totalOlasStakedBalance;
-
- if (minimumOlasRequiredToMigrate === undefined) return false;
-
- return balanceForMigration >= minimumOlasRequiredToMigrate;
- }, [minimumOlasRequiredToMigrate, safeBalance?.OLAS, totalOlasStakedBalance]);
-
- const hasEnoughSlots =
- stakingContractInfoForStakingProgram?.maxNumServices &&
- stakingContractInfoForStakingProgram?.serviceIds &&
- stakingContractInfoForStakingProgram?.maxNumServices >
- stakingContractInfoForStakingProgram?.serviceIds?.length;
-
- // TODO: compatibility needs to be implemented
- const isAppVersionCompatible = true; // contract.appVersion === 'rc105';
-
- const isMigratable =
- !isSelected &&
- activeStakingProgram === StakingProgram.Alpha && // TODO: make more elegant
- isBalanceLoaded &&
- hasEnoughSlots &&
- hasEnoughRewards &&
- hasEnoughOlasToMigrate &&
- isAppVersionCompatible &&
- serviceStatus !== DeploymentStatus.DEPLOYED &&
- serviceStatus !== DeploymentStatus.DEPLOYING &&
- serviceStatus !== DeploymentStatus.STOPPING &&
- isServiceStakedForMinimumDuration;
-
- const cantMigrateReason = useMemo(() => {
- if (isSelected) {
- return 'Contract is already selected';
- }
-
- if (!hasEnoughRewards) {
- return 'No available rewards';
- }
-
- if (activeStakingProgram !== StakingProgram.Alpha) {
- return 'Can only migrate from Alpha to Beta';
- }
+ const stakingProgramMeta = STAKING_PROGRAM_META[stakingProgramId];
- if (!isBalanceLoaded) {
- return 'Loading balance...';
- }
-
- if (!hasEnoughSlots) {
- return 'No available staking slots';
- }
-
- if (!hasEnoughOlasToMigrate) {
- return `Insufficient OLAS to migrate, ${minimumOlasRequiredToMigrate} OLAS required in total.`;
- }
-
- if (!isAppVersionCompatible) {
- return 'Pearl update required to migrate';
- }
-
- if (serviceStatus === DeploymentStatus.DEPLOYED) {
- return 'Service is currently running';
- }
-
- if (serviceStatus === DeploymentStatus.DEPLOYING) {
- return 'Service is currently deploying';
- }
-
- if (serviceStatus === DeploymentStatus.STOPPING) {
- return 'Service is currently stopping';
- }
-
- if (!isServiceStakedForMinimumDuration) {
- return 'Service has not been staked for the minimum duration';
- }
- }, [
- activeStakingProgram,
- hasEnoughOlasToMigrate,
- hasEnoughRewards,
- hasEnoughSlots,
- isAppVersionCompatible,
- isBalanceLoaded,
- isSelected,
- isServiceStakedForMinimumDuration,
- minimumOlasRequiredToMigrate,
- serviceStatus,
- ]);
-
- const cantMigrateAlert = useMemo(() => {
- if (isSelected || !isBalanceLoaded) {
- return null;
- }
-
- if (!hasEnoughSlots) {
- return ;
- }
-
- if (
- !hasEnoughOlasToMigrate &&
- safeBalance?.OLAS !== undefined &&
- totalOlasStakedBalance !== undefined
- ) {
- return (
-
- );
- }
-
- if (!isAppVersionCompatible) {
- return ;
- }
- }, [
- isSelected,
- isBalanceLoaded,
- hasEnoughSlots,
- hasEnoughOlasToMigrate,
- isAppVersionCompatible,
- safeBalance?.OLAS,
- totalOlasStakedBalance,
- minimumOlasRequiredToMigrate,
- ]);
+ /**
+ * Returns `true` if this stakingProgram is active,
+ * or user is unstaked and this is the default
+ */
+ const isActiveStakingProgram = useMemo(() => {
+ if (activeStakingProgramId === null)
+ return defaultStakingProgramId === stakingProgramId;
+ return activeStakingProgramId === stakingProgramId;
+ }, [activeStakingProgramId, defaultStakingProgramId, stakingProgramId]);
const contractTagStatus = useMemo(() => {
- if (activeStakingProgram === stakingProgram)
+ if (activeStakingProgramId === stakingProgramId)
return StakingProgramStatus.Selected;
- // Pearl is not staked, set as Selected if default (Beta)
- if (!activeStakingProgram && stakingProgram === defaultStakingProgram)
+ // Pearl is not staked, set as Selected if default
+ if (!activeStakingProgramId && stakingProgramId === defaultStakingProgramId)
return StakingProgramStatus.Selected;
- // Otherwise, highlight Beta as New
- if (stakingProgram === StakingProgram.Beta) return StakingProgramStatus.New;
-
// Otherwise, no tag
- return;
- }, [activeStakingProgram, defaultStakingProgram, stakingProgram]);
+ return null;
+ }, [activeStakingProgramId, defaultStakingProgramId, stakingProgramId]);
+
+ const showMigrateButton = !isActiveStakingProgram;
+ const showFundingButton = useMemo(() => {
+ if (migrateValidation.canMigrate) return false;
+ return (
+ migrateValidation.reason === CantMigrateReason.InsufficientOlasToMigrate
+ );
+ }, [migrateValidation]);
return (
<>
- {/* Title */}
- {`${activeStakingProgramMeta.name} contract`}
+
+ {`${stakingProgramMeta?.name} contract`}
+
- {!isSelected && (
- // here instead of isSelected we should check that the contract is not the old staking contract
- // but the one from staking factory (if we want to open govern)
-
- Contract details {UNICODE_SYMBOLS.EXTERNAL_LINK}
-
- )}
- {/* TODO: redisplay once bugs resolved */}
-
- {/* Contract details
- {stakingContractInfo?.availableRewards && (
-
- )}
-
- {stakingContractInfo?.minStakingDeposit && (
-
- )} */}
-
- {cantMigrateAlert}
- {/* Switch to program button */}
- {stakingProgram !== StakingProgram.Alpha && (
-
-
-
+
+
+ View contract details {UNICODE_SYMBOLS.EXTERNAL_LINK}
+
+
+ {!migrateValidation.canMigrate && (
+
)}
- {stakingProgram === StakingProgram.Beta && (
-
+
+ {showMigrateButton && (
+
)}
+ {showFundingButton && }
- {stakingProgram === StakingProgram.Beta && isFundingSectionOpen && (
-
- )}
>
);
};
diff --git a/frontend/components/ManageStakingPage/StakingContractSection/useMigrate.tsx b/frontend/components/ManageStakingPage/StakingContractSection/useMigrate.tsx
new file mode 100644
index 000000000..1a1ed4aba
--- /dev/null
+++ b/frontend/components/ManageStakingPage/StakingContractSection/useMigrate.tsx
@@ -0,0 +1,165 @@
+import { isNil } from 'lodash';
+import { useMemo } from 'react';
+
+import { DeploymentStatus } from '@/client';
+import { StakingProgramId } from '@/enums/StakingProgram';
+import { useBalance } from '@/hooks/useBalance';
+import { useServices } from '@/hooks/useServices';
+import { useServiceTemplates } from '@/hooks/useServiceTemplates';
+import { useStakingContractInfo } from '@/hooks/useStakingContractInfo';
+import { useStakingProgram } from '@/hooks/useStakingProgram';
+import { getMinimumStakedAmountRequired } from '@/utils/service';
+
+export enum CantMigrateReason {
+ ContractAlreadySelected = 'This staking program is already selected',
+ LoadingBalance = 'Loading balance...',
+ LoadingStakingContractInfo = 'Loading staking contract information...',
+ InsufficientOlasToMigrate = 'Insufficient OLAS to switch',
+ MigrationNotSupported = 'Switching to this program is not currently supported',
+ NoAvailableRewards = 'This program has no rewards available',
+ NoAvailableStakingSlots = 'The program has no more avaiable slots',
+ NotStakedForMinimumDuration = 'Pearl has not been staked for the required minimum duration',
+ PearlCurrentlyRunning = 'Unable to switch while Pearl is running',
+}
+
+type MigrateValidation =
+ | {
+ canMigrate: true;
+ }
+ | {
+ canMigrate: false;
+ reason: CantMigrateReason;
+ };
+
+export const useMigrate = (stakingProgramId: StakingProgramId) => {
+ const { serviceStatus } = useServices();
+ const { serviceTemplate } = useServiceTemplates();
+ const { isBalanceLoaded, safeBalance, totalOlasStakedBalance } = useBalance();
+ const { activeStakingProgramId, activeStakingProgramMeta } =
+ useStakingProgram();
+ const {
+ activeStakingContractInfo,
+ isServiceStaked,
+ isServiceStakedForMinimumDuration,
+ isStakingContractInfoLoaded,
+ isRewardsAvailable,
+ hasEnoughServiceSlots,
+ } = useStakingContractInfo();
+
+ const minimumOlasRequiredToMigrate = useMemo(
+ () => getMinimumStakedAmountRequired(serviceTemplate, stakingProgramId),
+ [serviceTemplate, stakingProgramId],
+ );
+
+ const hasEnoughOlasToMigrate = useMemo(() => {
+ if (!isBalanceLoaded) return false;
+ if (isNil(safeBalance?.OLAS)) return false;
+ if (isNil(totalOlasStakedBalance)) return false;
+ if (isNil(minimumOlasRequiredToMigrate)) return false;
+
+ const balanceForMigration = safeBalance.OLAS + totalOlasStakedBalance;
+
+ return balanceForMigration >= minimumOlasRequiredToMigrate;
+ }, [
+ isBalanceLoaded,
+ minimumOlasRequiredToMigrate,
+ safeBalance,
+ totalOlasStakedBalance,
+ ]);
+
+ const migrateValidation = useMemo(() => {
+ // loading requirements
+ if (!isBalanceLoaded) {
+ return { canMigrate: false, reason: CantMigrateReason.LoadingBalance };
+ }
+
+ if (!isStakingContractInfoLoaded) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.LoadingStakingContractInfo,
+ };
+ }
+
+ // general requirements
+ if (activeStakingProgramId === stakingProgramId) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.ContractAlreadySelected,
+ };
+ }
+
+ if (!isRewardsAvailable) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.NoAvailableRewards,
+ };
+ }
+
+ if (!hasEnoughServiceSlots) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.NoAvailableStakingSlots,
+ };
+ }
+
+ if (!hasEnoughOlasToMigrate) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.InsufficientOlasToMigrate,
+ };
+ }
+
+ // Services must be not be running or in a transitional state
+ if (
+ [
+ DeploymentStatus.DEPLOYED,
+ DeploymentStatus.DEPLOYING,
+ DeploymentStatus.STOPPING,
+ ].some((status) => status === serviceStatus)
+ ) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.PearlCurrentlyRunning,
+ };
+ }
+
+ if (activeStakingProgramId === null && !isServiceStaked) {
+ return { canMigrate: true };
+ }
+
+ // user must be staked from hereon
+
+ if (!activeStakingProgramMeta?.canMigrateTo.includes(stakingProgramId)) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.MigrationNotSupported,
+ };
+ }
+
+ if (activeStakingContractInfo && !isServiceStakedForMinimumDuration) {
+ return {
+ canMigrate: false,
+ reason: CantMigrateReason.NotStakedForMinimumDuration,
+ };
+ }
+
+ return { canMigrate: true };
+ }, [
+ isBalanceLoaded,
+ isStakingContractInfoLoaded,
+ activeStakingProgramId,
+ stakingProgramId,
+ isRewardsAvailable,
+ hasEnoughServiceSlots,
+ hasEnoughOlasToMigrate,
+ isServiceStaked,
+ activeStakingProgramMeta?.canMigrateTo,
+ activeStakingContractInfo,
+ isServiceStakedForMinimumDuration,
+ serviceStatus,
+ ]);
+
+ return {
+ migrateValidation,
+ };
+};
diff --git a/frontend/components/ManageStakingPage/index.tsx b/frontend/components/ManageStakingPage/index.tsx
index 82938256f..f58d07467 100644
--- a/frontend/components/ManageStakingPage/index.tsx
+++ b/frontend/components/ManageStakingPage/index.tsx
@@ -1,16 +1,56 @@
import { CloseOutlined } from '@ant-design/icons';
import { Button, Card } from 'antd';
+import { STAKING_PROGRAM_META } from '@/constants/stakingProgramMeta';
import { Pages } from '@/enums/PageState';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { usePageState } from '@/hooks/usePageState';
+import { useStakingProgram } from '@/hooks/useStakingProgram';
import { CardTitle } from '../Card/CardTitle';
+import { CardSection } from '../styled/CardSection';
import { StakingContractSection } from './StakingContractSection';
import { WhatAreStakingContractsSection } from './WhatAreStakingContracts';
export const ManageStakingPage = () => {
const { goto } = usePageState();
+ const { activeStakingProgramId, defaultStakingProgramId } =
+ useStakingProgram();
+
+ const orderedStakingProgramIds: StakingProgramId[] = Object.values(
+ StakingProgramId,
+ ).reduce((acc: StakingProgramId[], stakingProgramId: StakingProgramId) => {
+ // put the active staking program at the top
+ if (stakingProgramId === activeStakingProgramId) {
+ return [stakingProgramId, ...acc];
+ }
+
+ // put default at the top if no activeStakingProgram
+ if (
+ activeStakingProgramId === null &&
+ stakingProgramId === defaultStakingProgramId
+ )
+ return [stakingProgramId, ...acc];
+
+ // if the program is deprecated, ignore it
+ if (STAKING_PROGRAM_META[stakingProgramId]?.deprecated) {
+ return acc;
+ }
+
+ // otherwise, append to the end
+ return [...acc, stakingProgramId];
+ }, []);
+
+ const otherStakingProgramIds = orderedStakingProgramIds.filter(
+ (stakingProgramId) => {
+ const info = STAKING_PROGRAM_META[stakingProgramId];
+ if (!info) return false;
+ if (activeStakingProgramId === stakingProgramId) return false;
+ if (info.deprecated) return false;
+ return true;
+ },
+ );
+
return (
}
@@ -24,8 +64,23 @@ export const ManageStakingPage = () => {
}
>
-
-
+
+ {activeStakingProgramId && (
+
+ )}
+
+
+ {`Browse ${otherStakingProgramIds.length} staking contract${otherStakingProgramIds.length > 1 ? 's' : ''}.`}
+
+
+ {otherStakingProgramIds.map((stakingProgramId) => (
+
+ ))}
);
};
diff --git a/frontend/components/SettingsPage/DebugInfoSection.tsx b/frontend/components/SettingsPage/DebugInfoSection.tsx
index 4fa00aebf..0bb775e76 100644
--- a/frontend/components/SettingsPage/DebugInfoSection.tsx
+++ b/frontend/components/SettingsPage/DebugInfoSection.tsx
@@ -175,7 +175,7 @@ export const DebugInfoSection = () => {
?.instances?.[0];
if (instanceAddress) {
result.push({
- title: 'Agent instance',
+ title: 'Agent Instance EOA',
...getItemData(walletBalances, instanceAddress!),
});
}
@@ -186,10 +186,6 @@ export const DebugInfoSection = () => {
result.push({
title: 'Agent Safe',
...getItemData(walletBalances, multisigAddress),
- link: {
- title: 'See agent activity on Pandora',
- href: `https://pandora.computer/predict/${multisigAddress}`,
- },
});
}
diff --git a/frontend/components/SettingsPage/SettingsStakingContractSection.tsx b/frontend/components/SettingsPage/SettingsStakingContractSection.tsx
deleted file mode 100644
index 121b36476..000000000
--- a/frontend/components/SettingsPage/SettingsStakingContractSection.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import { Button, Flex, Skeleton, Typography } from 'antd';
-
-import { Chain } from '@/client';
-import { SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES } from '@/constants/contractAddresses';
-import { UNICODE_SYMBOLS } from '@/constants/symbols';
-import { Pages } from '@/enums/PageState';
-import { usePageState } from '@/hooks/usePageState';
-import { useStakingProgram } from '@/hooks/useStakingProgram';
-
-import { CardSection } from '../styled/CardSection';
-
-const { Text } = Typography;
-
-export const SettingsStakingContractSection = () => {
- const { goto } = usePageState();
- const {
- activeStakingProgram,
- activeStakingProgramMeta,
- defaultStakingProgram,
- isLoadedActiveStakingProgram,
- } = useStakingProgram();
-
- const stakingContractAddress =
- SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS][
- activeStakingProgram ?? defaultStakingProgram
- ];
-
- if (!isLoadedActiveStakingProgram) {
- return ;
- }
-
- return (
-
- Staking contract
-
-
- {activeStakingProgramMeta
- ? activeStakingProgramMeta.name
- : 'Not staked'}
-
-
- Contract details {UNICODE_SYMBOLS.EXTERNAL_LINK}
-
-
-
-
- );
-};
diff --git a/frontend/components/SettingsPage/index.tsx b/frontend/components/SettingsPage/index.tsx
index 3170d1e54..76f5b01c7 100644
--- a/frontend/components/SettingsPage/index.tsx
+++ b/frontend/components/SettingsPage/index.tsx
@@ -16,7 +16,6 @@ import { CardTitle } from '../Card/CardTitle';
import { CardSection } from '../styled/CardSection';
import { AddBackupWalletPage } from './AddBackupWalletPage';
import { DebugInfoSection } from './DebugInfoSection';
-import { SettingsStakingContractSection } from './SettingsStakingContractSection';
const { Text, Paragraph } = Typography;
@@ -76,6 +75,7 @@ const SettingsMain = () => {
********
+
{/* Wallet backup */}
Backup wallet
@@ -91,8 +91,7 @@ const SettingsMain = () => {
)}
- {/* Staking contract section */}
-
+
{/* Debug info */}
@@ -114,7 +113,10 @@ const NoBackupWallet = () => {
<>
Your funds are at risk!
- You will lose any assets you send on other chains.
+
+ Add a backup wallet to allow you to retrieve funds if you lose
+ your password and seed phrase.
+
>
}
diff --git a/frontend/components/SetupPage/SetupWelcome.tsx b/frontend/components/SetupPage/SetupWelcome.tsx
index b12c2ebfa..9d3c3b3d8 100644
--- a/frontend/components/SetupPage/SetupWelcome.tsx
+++ b/frontend/components/SetupPage/SetupWelcome.tsx
@@ -39,12 +39,13 @@ export const SetupWelcome = () => {
case true:
setIsSetup(AccountIsSetup.True);
break;
- case false:
+ case false: {
// Reset persistent state
// if creating new account
electronApi.store?.clear?.();
setIsSetup(AccountIsSetup.False);
break;
+ }
default:
setIsSetup(AccountIsSetup.Error);
break;
@@ -64,18 +65,27 @@ export const SetupWelcome = () => {
return ;
case AccountIsSetup.Loading:
return (
-
+
);
- default:
+ case AccountIsSetup.Error:
return (
-
+
- Error determining account setup state.
+ Unable to determine the account setup status, please try again.
);
+ default:
+ return null;
}
}, [isSetup]);
diff --git a/frontend/constants/colors.ts b/frontend/constants/colors.ts
index 7625d03ee..69678c0ed 100644
--- a/frontend/constants/colors.ts
+++ b/frontend/constants/colors.ts
@@ -3,6 +3,7 @@ export const COLOR = {
GREEN_2: '#00F422',
PURPLE: '#722ed1',
PURPLE_DARK: '#36075F',
+ PURPLE_LIGHT: '#EFCFFF',
BLUE: '#1677FF',
ORANGE: '#FAAD14',
WHITE: '#ffffff',
diff --git a/frontend/constants/contractAddresses.ts b/frontend/constants/contractAddresses.ts
index bf76ee672..f22eebd2b 100644
--- a/frontend/constants/contractAddresses.ts
+++ b/frontend/constants/contractAddresses.ts
@@ -1,5 +1,5 @@
import { Chain } from '@/client';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { Address } from '@/types/Address';
export const MULTICALL_CONTRACT_ADDRESS: Address =
@@ -18,12 +18,12 @@ export const SERVICE_REGISTRY_TOKEN_UTILITY_CONTRACT_ADDRESS: Record<
export const SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES: Record<
number,
- Record
+ Record
> = {
[Chain.GNOSIS]: {
- // Maintain order, as it is used in the UI
- [StakingProgram.Beta]: '0xeF44Fb0842DDeF59D37f85D61A1eF492bbA6135d',
- [StakingProgram.Alpha]: '0xEE9F19b5DF06c7E8Bfc7B28745dcf944C504198A',
+ [StakingProgramId.Beta2]: '0x1c2F82413666d2a3fD8bC337b0268e62dDF67434',
+ [StakingProgramId.Beta]: '0xeF44Fb0842DDeF59D37f85D61A1eF492bbA6135d',
+ [StakingProgramId.Alpha]: '0xEE9F19b5DF06c7E8Bfc7B28745dcf944C504198A',
},
};
diff --git a/frontend/constants/serviceTemplates.ts b/frontend/constants/serviceTemplates.ts
index 19948f76a..6a4b2ebe1 100644
--- a/frontend/constants/serviceTemplates.ts
+++ b/frontend/constants/serviceTemplates.ts
@@ -1,10 +1,10 @@
import { ServiceTemplate } from '@/client';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
export const SERVICE_TEMPLATES: ServiceTemplate[] = [
{
name: 'Trader Agent',
- hash: 'bafybeicrstlxew36hlxl7pzi73nmd44aibnhwxzkchzlec6t6yhvs7gvhy',
+ hash: 'bafybeidu3e3hdx5qt3bclheo7opr4adiil6zs2cger6m733qvhttnlo6na',
// hash: 'bafybeibbloa4w33vj4bvdkso7pzk6tr3duvxjpecbx4mur4ix6ehnwb5uu', // temporary
description: 'Trader agent for omen prediction markets',
image:
@@ -13,7 +13,7 @@ export const SERVICE_TEMPLATES: ServiceTemplate[] = [
home_chain_id: '100',
configurations: {
100: {
- staking_program_id: StakingProgram.Beta, // default, may be overwritten
+ staking_program_id: StakingProgramId.Beta, // default, may be overwritten
nft: 'bafybeig64atqaladigoc3ds4arltdu63wkdrk3gesjfvnfdmz35amv7faq',
agent_id: 14,
threshold: 1,
diff --git a/frontend/constants/stakingProgramMeta.ts b/frontend/constants/stakingProgramMeta.ts
index f060c3ab2..4fabb4c6d 100644
--- a/frontend/constants/stakingProgramMeta.ts
+++ b/frontend/constants/stakingProgramMeta.ts
@@ -1,15 +1,27 @@
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
+export type StakingProgramMeta = {
+ name: string;
+ canMigrateTo: StakingProgramId[];
+ deprecated: boolean;
+};
export const STAKING_PROGRAM_META: Record<
- StakingProgram,
- {
- name: string;
- }
+ StakingProgramId,
+ StakingProgramMeta
> = {
- [StakingProgram.Alpha]: {
+ [StakingProgramId.Alpha]: {
name: 'Pearl Alpha',
+ canMigrateTo: [StakingProgramId.Beta, StakingProgramId.Beta2],
+ deprecated: true,
},
- [StakingProgram.Beta]: {
+ [StakingProgramId.Beta]: {
name: 'Pearl Beta',
+ canMigrateTo: [StakingProgramId.Beta2],
+ deprecated: false,
+ },
+ [StakingProgramId.Beta2]: {
+ name: 'Pearl Beta 2',
+ canMigrateTo: [StakingProgramId.Beta],
+ deprecated: false,
},
};
diff --git a/frontend/context/BalanceProvider.tsx b/frontend/context/BalanceProvider.tsx
index 2bee8e074..d9cbae01f 100644
--- a/frontend/context/BalanceProvider.tsx
+++ b/frontend/context/BalanceProvider.tsx
@@ -132,9 +132,11 @@ export const BalanceProvider = ({ children }: PropsWithChildren) => {
try {
const walletAddresses: Address[] = [];
- if (masterEoaAddress) walletAddresses.push(masterEoaAddress);
- if (masterSafeAddress) walletAddresses.push(masterSafeAddress);
- if (serviceAddresses) walletAddresses.push(...serviceAddresses);
+ if (isAddress(masterEoaAddress)) walletAddresses.push(masterEoaAddress);
+ if (isAddress(`${masterSafeAddress}`))
+ walletAddresses.push(masterSafeAddress as Address);
+ if (serviceAddresses)
+ walletAddresses.push(...serviceAddresses.filter(isAddress));
const walletBalances = await getWalletBalances(walletAddresses);
if (!walletBalances) return;
@@ -150,10 +152,10 @@ export const BalanceProvider = ({ children }: PropsWithChildren) => {
return;
}
- if (masterSafeAddress && serviceId) {
+ if (isAddress(`${masterSafeAddress}`) && serviceId > 0) {
const { depositValue, bondValue, serviceState } =
await AutonolasService.getServiceRegistryInfo(
- masterSafeAddress,
+ masterSafeAddress as Address,
serviceId,
);
diff --git a/frontend/context/ElectronApiProvider.tsx b/frontend/context/ElectronApiProvider.tsx
index 01f85bdf9..7927bf7d4 100644
--- a/frontend/context/ElectronApiProvider.tsx
+++ b/frontend/context/ElectronApiProvider.tsx
@@ -4,6 +4,7 @@ import { createContext, PropsWithChildren } from 'react';
import { ElectronStore, ElectronTrayIconStatus } from '@/types/ElectronApi';
type ElectronApiContextProps = {
+ setIsAppLoaded?: (isLoaded: boolean) => void;
closeApp?: () => void;
minimizeApp?: () => void;
setTrayIcon?: (status: ElectronTrayIconStatus) => void;
@@ -33,6 +34,7 @@ type ElectronApiContextProps = {
};
export const ElectronApiContext = createContext({
+ setIsAppLoaded: () => false,
closeApp: () => {},
minimizeApp: () => {},
setTrayIcon: () => {},
@@ -70,6 +72,7 @@ export const ElectronApiProvider = ({ children }: PropsWithChildren) => {
return (
{
const service = useMemo(() => services?.[0], [services]);
const { storeState } = useStore();
const electronApi = useElectronApi();
- const { activeStakingProgram, defaultStakingProgram } = useContext(
+ const { activeStakingProgramId, defaultStakingProgramId } = useContext(
StakingProgramContext,
);
@@ -76,7 +76,7 @@ export const RewardProvider = ({ children }: PropsWithChildren) => {
// only check for rewards if there's a currentStakingProgram active
if (
- activeStakingProgram &&
+ activeStakingProgramId &&
service?.chain_configs[CHAINS.GNOSIS.chainId].chain_data?.multisig &&
service?.chain_configs[CHAINS.GNOSIS.chainId].chain_data?.token
) {
@@ -85,13 +85,13 @@ export const RewardProvider = ({ children }: PropsWithChildren) => {
service.chain_configs[CHAINS.GNOSIS.chainId].chain_data.multisig!,
serviceId:
service.chain_configs[CHAINS.GNOSIS.chainId].chain_data.token!,
- stakingProgram: activeStakingProgram,
+ stakingProgram: activeStakingProgramId,
});
}
// can fallback to default staking program if no current staking program is active
const epochRewardsPromise = AutonolasService.getAvailableRewardsForEpoch(
- activeStakingProgram ?? defaultStakingProgram,
+ activeStakingProgramId ?? defaultStakingProgramId,
);
const [stakingRewardsInfo, rewards] = await Promise.all([
@@ -104,7 +104,7 @@ export const RewardProvider = ({ children }: PropsWithChildren) => {
stakingRewardsInfo?.accruedServiceStakingRewards,
);
setAvailableRewardsForEpoch(rewards);
- }, [activeStakingProgram, defaultStakingProgram, service]);
+ }, [activeStakingProgramId, defaultStakingProgramId, service]);
useEffect(() => {
if (isEligibleForRewards && !storeState?.firstStakingRewardAchieved) {
diff --git a/frontend/context/StakingContractInfoProvider.tsx b/frontend/context/StakingContractInfoProvider.tsx
index 6bf19408a..71910cb2d 100644
--- a/frontend/context/StakingContractInfoProvider.tsx
+++ b/frontend/context/StakingContractInfoProvider.tsx
@@ -11,7 +11,7 @@ import { useInterval } from 'usehooks-ts';
import { CHAINS } from '@/constants/chains';
import { FIVE_SECONDS_INTERVAL } from '@/constants/intervals';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { AutonolasService } from '@/service/Autonolas';
import { StakingContractInfo } from '@/types/Autonolas';
@@ -19,32 +19,37 @@ import { ServicesContext } from './ServicesProvider';
import { StakingProgramContext } from './StakingProgramContext';
type StakingContractInfoContextProps = {
- updateActiveStakingContractInfo: () => Promise;
- activeStakingContractInfo?: StakingContractInfo;
+ activeStakingContractInfo?: Partial;
+ isStakingContractInfoLoaded: boolean;
stakingContractInfoRecord?: Record<
- StakingProgram,
+ StakingProgramId,
Partial
>;
+ updateActiveStakingContractInfo: () => Promise;
};
export const StakingContractInfoContext =
createContext({
- updateActiveStakingContractInfo: async () => {},
activeStakingContractInfo: undefined,
+ isStakingContractInfoLoaded: false,
stakingContractInfoRecord: undefined,
+ updateActiveStakingContractInfo: async () => {},
});
export const StakingContractInfoProvider = ({
children,
}: PropsWithChildren) => {
const { services } = useContext(ServicesContext);
- const { activeStakingProgram } = useContext(StakingProgramContext);
+ const { activeStakingProgramId } = useContext(StakingProgramContext);
+
+ const [isStakingContractInfoLoaded, setIsStakingContractInfoLoaded] =
+ useState(false);
const [activeStakingContractInfo, setActiveStakingContractInfo] =
- useState();
+ useState>();
const [stakingContractInfoRecord, setStakingContractInfoRecord] =
- useState>>();
+ useState>>();
const serviceId = useMemo(
() => services?.[0]?.chain_configs[CHAINS.GNOSIS.chainId].chain_data?.token,
@@ -55,33 +60,45 @@ export const StakingContractInfoProvider = ({
// it requires serviceId and activeStakingProgram
const updateActiveStakingContractInfo = useCallback(async () => {
if (!serviceId) return;
- if (!activeStakingProgram) return;
+ if (!activeStakingProgramId) return;
AutonolasService.getStakingContractInfoByServiceIdStakingProgram(
serviceId,
- activeStakingProgram,
+ activeStakingProgramId,
).then(setActiveStakingContractInfo);
- }, [activeStakingProgram, serviceId]);
+ }, [activeStakingProgramId, serviceId]);
useInterval(updateActiveStakingContractInfo, FIVE_SECONDS_INTERVAL);
// Record of staking contract info for each staking program
// not user/service specific
- const updateStakingContractInfoRecord = () => {
+ const updateStakingContractInfoRecord = async () => {
const alpha = AutonolasService.getStakingContractInfoByStakingProgram(
- StakingProgram.Alpha,
+ StakingProgramId.Alpha,
);
const beta = AutonolasService.getStakingContractInfoByStakingProgram(
- StakingProgram.Beta,
+ StakingProgramId.Beta,
);
- Promise.all([alpha, beta]).then((values) => {
- const [alphaInfo, betaInfo] = values;
+ const beta_2 = AutonolasService.getStakingContractInfoByStakingProgram(
+ StakingProgramId.Beta2,
+ );
+
+ try {
+ const [alphaInfo, betaInfo, beta2Info] = await Promise.all([
+ alpha,
+ beta,
+ beta_2,
+ ]);
setStakingContractInfoRecord({
- [StakingProgram.Alpha]: alphaInfo,
- [StakingProgram.Beta]: betaInfo,
+ [StakingProgramId.Alpha]: alphaInfo,
+ [StakingProgramId.Beta]: betaInfo,
+ [StakingProgramId.Beta2]: beta2Info,
});
- });
+ setIsStakingContractInfoLoaded(true);
+ } catch (e) {
+ setIsStakingContractInfoLoaded(false);
+ }
};
useEffect(() => {
@@ -92,9 +109,10 @@ export const StakingContractInfoProvider = ({
return (
{children}
diff --git a/frontend/context/StakingProgramContext.tsx b/frontend/context/StakingProgramContext.tsx
index fecdf645c..39e6ba2ab 100644
--- a/frontend/context/StakingProgramContext.tsx
+++ b/frontend/context/StakingProgramContext.tsx
@@ -2,55 +2,55 @@ import { createContext, PropsWithChildren, useCallback, useState } from 'react';
import { useInterval } from 'usehooks-ts';
import { CHAINS } from '@/constants/chains';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { useServices } from '@/hooks/useServices';
import { AutonolasService } from '@/service/Autonolas';
export const StakingProgramContext = createContext<{
- activeStakingProgram?: StakingProgram | null;
- defaultStakingProgram: StakingProgram;
- updateActiveStakingProgram: () => Promise;
+ activeStakingProgramId?: StakingProgramId | null;
+ defaultStakingProgramId: StakingProgramId;
+ updateActiveStakingProgramId: () => Promise;
}>({
- activeStakingProgram: undefined,
- defaultStakingProgram: StakingProgram.Beta,
- updateActiveStakingProgram: async () => {},
+ activeStakingProgramId: undefined,
+ defaultStakingProgramId: StakingProgramId.Beta,
+ updateActiveStakingProgramId: async () => {},
});
/** Determines the current active staking program, if any */
export const StakingProgramProvider = ({ children }: PropsWithChildren) => {
const { service } = useServices();
- const [activeStakingProgram, setActiveStakingProgram] =
- useState();
+ const [activeStakingProgramId, setActiveStakingProgramId] =
+ useState();
- const updateActiveStakingProgram = useCallback(async () => {
+ const updateActiveStakingProgramId = useCallback(async () => {
// if no service nft, not staked
const serviceId =
service?.chain_configs[CHAINS.GNOSIS.chainId].chain_data?.token;
if (!service?.chain_configs[CHAINS.GNOSIS.chainId].chain_data?.token) {
- setActiveStakingProgram(null);
+ setActiveStakingProgramId(null);
return;
}
if (serviceId) {
// if service exists, we need to check if it is staked
AutonolasService.getCurrentStakingProgramByServiceId(serviceId).then(
- (stakingProgram) => {
- setActiveStakingProgram(stakingProgram);
+ (stakingProgramId) => {
+ setActiveStakingProgramId(stakingProgramId);
},
);
}
}, [service]);
- useInterval(updateActiveStakingProgram, 5000);
+ useInterval(updateActiveStakingProgramId, 5000);
return (
{children}
diff --git a/frontend/enums/StakingProgram.ts b/frontend/enums/StakingProgram.ts
index c3d98cd42..dc5a16da9 100644
--- a/frontend/enums/StakingProgram.ts
+++ b/frontend/enums/StakingProgram.ts
@@ -1,4 +1,5 @@
-export enum StakingProgram {
+export enum StakingProgramId {
Alpha = 'pearl_alpha',
Beta = 'pearl_beta',
+ Beta2 = 'pearl_beta_2',
}
diff --git a/frontend/enums/StakingProgramStatus.ts b/frontend/enums/StakingProgramStatus.ts
index d2789f1ef..d161434b7 100644
--- a/frontend/enums/StakingProgramStatus.ts
+++ b/frontend/enums/StakingProgramStatus.ts
@@ -1,4 +1,3 @@
export enum StakingProgramStatus {
- New = 'new',
Selected = 'current',
}
diff --git a/frontend/hooks/useNeedsFunds.ts b/frontend/hooks/useNeedsFunds.ts
new file mode 100644
index 000000000..f99e909a9
--- /dev/null
+++ b/frontend/hooks/useNeedsFunds.ts
@@ -0,0 +1,71 @@
+import { formatUnits } from 'ethers/lib/utils';
+import { useMemo } from 'react';
+
+import { CHAINS } from '@/constants/chains';
+import { getMinimumStakedAmountRequired } from '@/utils/service';
+
+import { useBalance } from './useBalance';
+import { useServiceTemplates } from './useServiceTemplates';
+import { useStore } from './useStore';
+
+export const useNeedsFunds = () => {
+ const { getServiceTemplates } = useServiceTemplates();
+
+ const serviceTemplate = useMemo(
+ () => getServiceTemplates()[0],
+ [getServiceTemplates],
+ );
+
+ const { storeState } = useStore();
+ const { isBalanceLoaded, safeBalance, totalOlasStakedBalance } = useBalance();
+
+ const serviceFundRequirements = useMemo(() => {
+ const gasEstimate =
+ serviceTemplate.configurations[CHAINS.GNOSIS.chainId]
+ .monthly_gas_estimate;
+ const monthlyGasEstimate = Number(formatUnits(`${gasEstimate}`, 18));
+ const minimumStakedAmountRequired =
+ getMinimumStakedAmountRequired(serviceTemplate);
+
+ return { eth: monthlyGasEstimate, olas: minimumStakedAmountRequired };
+ }, [serviceTemplate]);
+
+ const hasEnoughEthForInitialFunding = useMemo(
+ () => (safeBalance?.ETH || 0) >= (serviceFundRequirements?.eth || 0),
+ [serviceFundRequirements?.eth, safeBalance],
+ );
+
+ const hasEnoughOlasForInitialFunding = useMemo(() => {
+ const olasInSafe = safeBalance?.OLAS || 0;
+ const olasStakedBySafe = totalOlasStakedBalance || 0;
+ const olasRequiredToFundService = serviceFundRequirements.olas || 0;
+ const olasInSafeAndStaked = olasInSafe + olasStakedBySafe;
+ return olasInSafeAndStaked >= olasRequiredToFundService;
+ }, [
+ safeBalance?.OLAS,
+ totalOlasStakedBalance,
+ serviceFundRequirements?.olas,
+ ]);
+
+ const isInitialFunded = storeState?.isInitialFunded;
+ const needsInitialFunding: boolean = useMemo(() => {
+ if (isInitialFunded) return false;
+ if (!isBalanceLoaded) return false;
+ if (hasEnoughEthForInitialFunding && hasEnoughOlasForInitialFunding)
+ return false;
+ return true;
+ }, [
+ hasEnoughEthForInitialFunding,
+ hasEnoughOlasForInitialFunding,
+ isBalanceLoaded,
+ isInitialFunded,
+ ]);
+
+ return {
+ hasEnoughEthForInitialFunding,
+ hasEnoughOlasForInitialFunding,
+ serviceFundRequirements,
+ isInitialFunded,
+ needsInitialFunding,
+ };
+};
diff --git a/frontend/hooks/useStakingContractInfo.ts b/frontend/hooks/useStakingContractInfo.ts
index 460f74613..9cf911ffd 100644
--- a/frontend/hooks/useStakingContractInfo.ts
+++ b/frontend/hooks/useStakingContractInfo.ts
@@ -1,3 +1,4 @@
+import { isNil } from 'lodash';
import { useContext } from 'react';
import { StakingContractInfoContext } from '@/context/StakingContractInfoProvider';
@@ -5,9 +6,11 @@ import { StakingContractInfoContext } from '@/context/StakingContractInfoProvide
import { useServices } from './useServices';
export const useStakingContractInfo = () => {
- const { activeStakingContractInfo, stakingContractInfoRecord } = useContext(
- StakingContractInfoContext,
- );
+ const {
+ activeStakingContractInfo,
+ stakingContractInfoRecord,
+ isStakingContractInfoLoaded,
+ } = useContext(StakingContractInfoContext);
const { services } = useServices();
@@ -17,19 +20,28 @@ export const useStakingContractInfo = () => {
const {
serviceStakingState,
serviceStakingStartTime,
- availableRewards,
+ //availableRewards, // TODO: uncomment when availableRewards is available
serviceIds,
maxNumServices,
minimumStakingDuration,
} = activeStakingContractInfo;
const isRewardsAvailable = true; // availableRewards > 0;
- const hasEnoughServiceSlots = serviceIds.length < maxNumServices;
+
+ const hasEnoughServiceSlots =
+ !isNil(serviceIds) &&
+ !isNil(maxNumServices) &&
+ serviceIds.length < maxNumServices;
+
const hasEnoughRewardsAndSlots = isRewardsAvailable && hasEnoughServiceSlots;
const isAgentEvicted = serviceStakingState === 2;
+ const isServiceStaked =
+ !!serviceStakingStartTime && serviceStakingState === 1;
+
/**
+ * Important: Assumes service is staked. Returns false for unstaked.
* For example: minStakingDuration = 3 days
*
* - Service starts staking 1st June 00:01
@@ -41,25 +53,31 @@ export const useStakingContractInfo = () => {
*
*/
const isServiceStakedForMinimumDuration =
+ !isNil(serviceStakingStartTime) &&
+ !isNil(minimumStakingDuration) &&
Math.round(Date.now() / 1000) - serviceStakingStartTime >=
- minimumStakingDuration;
+ minimumStakingDuration;
/**
- * user can start the agent iff,
+ * User can only stake if:
* - rewards are available
* - service has enough slots
- * - if agent is evicted, then service should be staked for minimum duration
+ * - agent is not evicted
+ * - if agent is evicted, then service should be staked for minimum duration
*/
const isEligibleForStaking =
- hasEnoughRewardsAndSlots &&
+ !isNil(hasEnoughRewardsAndSlots) &&
(isAgentEvicted ? isServiceStakedForMinimumDuration : true);
return {
+ activeStakingContractInfo,
hasEnoughServiceSlots,
isEligibleForStaking,
isRewardsAvailable,
isAgentEvicted,
- stakingContractInfoRecord,
isServiceStakedForMinimumDuration,
+ isServiceStaked,
+ isStakingContractInfoLoaded,
+ stakingContractInfoRecord,
};
};
diff --git a/frontend/hooks/useStakingProgram.ts b/frontend/hooks/useStakingProgram.ts
index 8d07739be..560c8c811 100644
--- a/frontend/hooks/useStakingProgram.ts
+++ b/frontend/hooks/useStakingProgram.ts
@@ -1,33 +1,42 @@
-import { useContext } from 'react';
+import { useContext, useMemo } from 'react';
import { STAKING_PROGRAM_META } from '@/constants/stakingProgramMeta';
import { StakingProgramContext } from '@/context/StakingProgramContext';
/**
- * Mock hook for staking program abstraction
- * @returns {currentStakingProgram: IncentiveProgram}
+ * Hook to get the active staking program and its metadata, and the default staking program.
+ * @returns {Object} The active staking program and its metadata.
*/
export const useStakingProgram = () => {
const {
- activeStakingProgram,
- defaultStakingProgram,
- updateActiveStakingProgram: updateStakingProgram,
+ activeStakingProgramId,
+ defaultStakingProgramId,
+ updateActiveStakingProgramId,
} = useContext(StakingProgramContext);
- const isLoadedActiveStakingProgram = activeStakingProgram !== undefined;
+ const isActiveStakingProgramLoaded = activeStakingProgramId !== undefined;
- const activeStakingProgramMeta =
- activeStakingProgram === undefined
- ? null
- : activeStakingProgram === null
- ? null
- : STAKING_PROGRAM_META[activeStakingProgram];
+ /**
+ * TODO: implement enums
+ * returns `StakingProgramMeta` if defined
+ * returns `undefined` if not loaded
+ * returns `null` if not actively staked
+ */
+ const activeStakingProgramMeta = useMemo(() => {
+ if (activeStakingProgramId === undefined) return undefined;
+ if (activeStakingProgramId === null) return null;
+ return STAKING_PROGRAM_META[activeStakingProgramId];
+ }, [activeStakingProgramId]);
+
+ const defaultStakingProgramMeta =
+ STAKING_PROGRAM_META[defaultStakingProgramId];
return {
- activeStakingProgram,
+ activeStakingProgramId,
activeStakingProgramMeta,
- defaultStakingProgram,
- updateStakingProgram,
- isLoadedActiveStakingProgram,
+ defaultStakingProgramId,
+ defaultStakingProgramMeta,
+ isActiveStakingProgramLoaded,
+ updateActiveStakingProgramId,
};
};
diff --git a/frontend/package.json b/frontend/package.json
index ec20ee33a..0289f79d7 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -45,7 +45,7 @@
"private": true,
"scripts": {
"dev": "next dev",
- "build": "NODE_ENV=production next build",
+ "build": "bash -c \"DEV_RPC=$DEV_RPC FORK_URL=$FORK_URL NODE_ENV=production next build\"",
"lint": "next lint",
"test": "jest",
"start": "next start"
diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx
index 0eca2b8db..074a78b4b 100644
--- a/frontend/pages/index.tsx
+++ b/frontend/pages/index.tsx
@@ -16,6 +16,10 @@ export default function Home() {
const electronApi = useElectronApi();
useEffect(() => {
+ // Notify the main process that the app is loaded
+ electronApi?.setIsAppLoaded?.(true);
+
+ // Set the app height to the body scroll height
function updateAppHeight() {
const bodyElement = document.querySelector('body');
if (bodyElement) {
diff --git a/frontend/service/Autonolas.ts b/frontend/service/Autonolas.ts
index b0e9e74d6..ad5b91809 100644
--- a/frontend/service/Autonolas.ts
+++ b/frontend/service/Autonolas.ts
@@ -1,4 +1,5 @@
import { BigNumber, ethers } from 'ethers';
+import { formatEther } from 'ethers/lib/utils';
import { Contract as MulticallContract } from 'ethers-multicall';
import { AGENT_MECH_ABI } from '@/abis/agentMech';
@@ -16,10 +17,11 @@ import {
} from '@/constants/contractAddresses';
import { gnosisMulticallProvider } from '@/constants/providers';
import { ServiceRegistryL2ServiceState } from '@/enums/ServiceRegistryL2ServiceState';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
import { Address } from '@/types/Address';
import { StakingContractInfo, StakingRewardsInfo } from '@/types/Autonolas';
+const ONE_YEAR = 1 * 24 * 60 * 60 * 365;
const REQUIRED_MECH_REQUESTS_SAFETY_MARGIN = 1;
const agentMechContract = new MulticallContract(
@@ -27,25 +29,31 @@ const agentMechContract = new MulticallContract(
AGENT_MECH_ABI.filter((abi) => abi.type === 'function'), // weird bug in the package where their filter doesn't work..
);
+const ServiceStakingTokenAbi = SERVICE_STAKING_TOKEN_MECH_USAGE_ABI.filter(
+ (abi) => abi.type === 'function',
+);
+
const serviceStakingTokenMechUsageContracts: Record<
- StakingProgram,
+ StakingProgramId,
MulticallContract
> = {
- [StakingProgram.Alpha]: new MulticallContract(
+ [StakingProgramId.Alpha]: new MulticallContract(
+ SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS][
+ StakingProgramId.Alpha
+ ],
+ ServiceStakingTokenAbi,
+ ),
+ [StakingProgramId.Beta]: new MulticallContract(
SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS][
- StakingProgram.Alpha
+ StakingProgramId.Beta
],
- SERVICE_STAKING_TOKEN_MECH_USAGE_ABI.filter(
- (abi) => abi.type === 'function',
- ), // same as above
+ ServiceStakingTokenAbi,
),
- [StakingProgram.Beta]: new MulticallContract(
+ [StakingProgramId.Beta2]: new MulticallContract(
SERVICE_STAKING_TOKEN_MECH_USAGE_CONTRACT_ADDRESSES[Chain.GNOSIS][
- StakingProgram.Beta
+ StakingProgramId.Beta2
],
- SERVICE_STAKING_TOKEN_MECH_USAGE_ABI.filter(
- (abi) => abi.type === 'function',
- ), // same as above
+ ServiceStakingTokenAbi,
),
};
@@ -71,7 +79,7 @@ const getAgentStakingRewardsInfo = async ({
}: {
agentMultisigAddress: Address;
serviceId: number;
- stakingProgram: StakingProgram;
+ stakingProgram: StakingProgramId;
}): Promise => {
if (!agentMultisigAddress) return;
if (!serviceId) return;
@@ -161,20 +169,18 @@ const getAgentStakingRewardsInfo = async ({
};
const getAvailableRewardsForEpoch = async (
- stakingProgram: StakingProgram,
+ stakingProgramId: StakingProgramId,
): Promise => {
const contractCalls = [
- serviceStakingTokenMechUsageContracts[stakingProgram].rewardsPerSecond(),
- serviceStakingTokenMechUsageContracts[stakingProgram].livenessPeriod(), // epoch length
- serviceStakingTokenMechUsageContracts[stakingProgram].tsCheckpoint(), // last checkpoint timestamp
+ serviceStakingTokenMechUsageContracts[stakingProgramId].rewardsPerSecond(),
+ serviceStakingTokenMechUsageContracts[stakingProgramId].livenessPeriod(), // epoch length
+ serviceStakingTokenMechUsageContracts[stakingProgramId].tsCheckpoint(), // last checkpoint timestamp
];
await gnosisMulticallProvider.init();
const multicallResponse = await gnosisMulticallProvider.all(contractCalls);
-
const [rewardsPerSecond, livenessPeriod, tsCheckpoint] = multicallResponse;
-
const nowInSeconds = Math.floor(Date.now() / 1000);
return Math.max(
@@ -185,22 +191,24 @@ const getAvailableRewardsForEpoch = async (
const getStakingContractInfoByServiceIdStakingProgram = async (
serviceId: number,
- stakingProgram: StakingProgram,
-): Promise => {
+ stakingProgramId: StakingProgramId,
+): Promise | undefined> => {
if (!serviceId) return;
const contractCalls = [
- serviceStakingTokenMechUsageContracts[stakingProgram].availableRewards(),
- serviceStakingTokenMechUsageContracts[stakingProgram].maxNumServices(),
- serviceStakingTokenMechUsageContracts[stakingProgram].getServiceIds(),
- serviceStakingTokenMechUsageContracts[stakingProgram].minStakingDuration(),
- serviceStakingTokenMechUsageContracts[stakingProgram].getServiceInfo(
+ serviceStakingTokenMechUsageContracts[stakingProgramId].availableRewards(),
+ serviceStakingTokenMechUsageContracts[stakingProgramId].maxNumServices(),
+ serviceStakingTokenMechUsageContracts[stakingProgramId].getServiceIds(),
+ serviceStakingTokenMechUsageContracts[
+ stakingProgramId
+ ].minStakingDuration(),
+ serviceStakingTokenMechUsageContracts[stakingProgramId].getServiceInfo(
serviceId,
),
- serviceStakingTokenMechUsageContracts[stakingProgram].getStakingState(
+ serviceStakingTokenMechUsageContracts[stakingProgramId].getStakingState(
serviceId,
),
- serviceStakingTokenMechUsageContracts[stakingProgram].minStakingDeposit(),
+ serviceStakingTokenMechUsageContracts[stakingProgramId].minStakingDeposit(),
];
await gnosisMulticallProvider.init();
@@ -233,15 +241,22 @@ const getStakingContractInfoByServiceIdStakingProgram = async (
};
};
+/**
+ * Get staking contract info by staking program name
+ * eg. Alpha, Beta, Beta2
+ */
const getStakingContractInfoByStakingProgram = async (
- stakingProgram: StakingProgram,
-) => {
+ stakingProgram: StakingProgramId,
+): Promise> => {
const contractCalls = [
serviceStakingTokenMechUsageContracts[stakingProgram].availableRewards(),
serviceStakingTokenMechUsageContracts[stakingProgram].maxNumServices(),
serviceStakingTokenMechUsageContracts[stakingProgram].getServiceIds(),
serviceStakingTokenMechUsageContracts[stakingProgram].minStakingDuration(),
serviceStakingTokenMechUsageContracts[stakingProgram].minStakingDeposit(),
+ serviceStakingTokenMechUsageContracts[stakingProgram].rewardsPerSecond(),
+ serviceStakingTokenMechUsageContracts[stakingProgram].numAgentInstances(),
+ serviceStakingTokenMechUsageContracts[stakingProgram].livenessPeriod(),
];
await gnosisMulticallProvider.init();
@@ -253,6 +268,9 @@ const getStakingContractInfoByStakingProgram = async (
getServiceIdsInBN,
minStakingDurationInBN,
minStakingDeposit,
+ rewardsPerSecond,
+ numAgentInstances,
+ livenessPeriod,
] = multicallResponse;
const availableRewards = parseFloat(
@@ -261,12 +279,32 @@ const getStakingContractInfoByStakingProgram = async (
const serviceIds = getServiceIdsInBN.map((id: BigNumber) => id.toNumber());
const maxNumServices = maxNumServicesInBN.toNumber();
+ // APY
+ const rewardsPerYear = rewardsPerSecond.mul(ONE_YEAR);
+ const apy =
+ Number(rewardsPerYear.mul(100).div(minStakingDeposit)) /
+ (1 + numAgentInstances.toNumber());
+
+ // Amount of OLAS required for Stake
+ const stakeRequiredInWei = minStakingDeposit.add(
+ minStakingDeposit.mul(numAgentInstances),
+ );
+ const olasStakeRequired = Number(formatEther(stakeRequiredInWei));
+
+ // Rewards per work period
+ const rewardsPerWorkPeriod =
+ Number(formatEther(rewardsPerSecond as BigNumber)) *
+ livenessPeriod.toNumber();
+
return {
availableRewards,
maxNumServices,
serviceIds,
minimumStakingDuration: minStakingDurationInBN.toNumber(),
minStakingDeposit: parseFloat(ethers.utils.formatEther(minStakingDeposit)),
+ apy,
+ olasStakeRequired,
+ rewardsPerWorkPeriod,
};
};
@@ -308,30 +346,44 @@ const getServiceRegistryInfo = async (
};
};
+/**
+ * @param serviceId
+ * @returns StakingProgram | null (null when not staked)
+ */
const getCurrentStakingProgramByServiceId = async (
serviceId: number,
-): Promise => {
- const contractCalls = [
- serviceStakingTokenMechUsageContracts[StakingProgram.Alpha].getStakingState(
- serviceId,
- ),
- serviceStakingTokenMechUsageContracts[StakingProgram.Beta].getStakingState(
- serviceId,
- ),
- ];
-
- await gnosisMulticallProvider.init();
+): Promise => {
+ if (serviceId <= -1) return null;
+
+ const contractCalls = Object.values(StakingProgramId).reduce(
+ (acc, stakingProgramId: StakingProgramId) => ({
+ ...acc,
+ [stakingProgramId]:
+ serviceStakingTokenMechUsageContracts[stakingProgramId].getStakingState(
+ serviceId,
+ ),
+ }),
+ {},
+ );
try {
- const [isAlphaStaked, isBetaStaked] =
- await gnosisMulticallProvider.all(contractCalls);
-
- // Alpha should take precedence, as it must be migrated from
- return isAlphaStaked
- ? StakingProgram.Alpha
- : isBetaStaked
- ? StakingProgram.Beta
- : null;
+ await gnosisMulticallProvider.init();
+ const [isAlphaStaked, isBetaStaked, isBeta2Staked] =
+ await gnosisMulticallProvider.all(Object.values(contractCalls));
+
+ if (isAlphaStaked) {
+ return StakingProgramId.Alpha;
+ }
+
+ if (isBetaStaked) {
+ return StakingProgramId.Beta;
+ }
+
+ if (isBeta2Staked) {
+ return StakingProgramId.Beta2;
+ }
+
+ return null;
} catch (error) {
console.error('Error while getting current staking program', error);
return null;
diff --git a/frontend/service/Services.ts b/frontend/service/Services.ts
index 44730835c..be0a2c637 100644
--- a/frontend/service/Services.ts
+++ b/frontend/service/Services.ts
@@ -1,6 +1,6 @@
import { Deployment, Service, ServiceHash, ServiceTemplate } from '@/client';
import { BACKEND_URL } from '@/constants/urls';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
/**
* Get a single service from the backend
@@ -32,11 +32,11 @@ const getServices = async (): Promise =>
const createService = async ({
deploy,
serviceTemplate,
- stakingProgram,
+ stakingProgramId,
}: {
deploy: boolean;
serviceTemplate: ServiceTemplate;
- stakingProgram: StakingProgram;
+ stakingProgramId: StakingProgramId;
}): Promise =>
new Promise((resolve, reject) =>
fetch(`${BACKEND_URL}/services`, {
@@ -47,7 +47,7 @@ const createService = async ({
configurations: {
100: {
...serviceTemplate.configurations[100],
- staking_program_id: stakingProgram,
+ staking_program_id: stakingProgramId,
rpc: `${process.env.GNOSIS_RPC}`,
},
},
diff --git a/frontend/types/Autonolas.ts b/frontend/types/Autonolas.ts
index 3cd552d1c..187e13249 100644
--- a/frontend/types/Autonolas.ts
+++ b/frontend/types/Autonolas.ts
@@ -16,10 +16,16 @@ export type StakingContractInfo = {
serviceIds: number[];
/** minimum staking duration (in seconds) */
minimumStakingDuration: number;
- /** time when service was staked (in seconds) */
+ /** time when service was staked (in seconds) - 0 = never staked */
serviceStakingStartTime: number;
/** 0: not staked, 1: staked, 2: unstaked - current state of the service */
serviceStakingState: number;
/** OLAS cost of staking */
minStakingDeposit: number;
+ /** annual percentage yield */
+ apy: number;
+ /** amount of OLAS required to stake */
+ olasStakeRequired: number;
+ /** rewards per work period */
+ rewardsPerWorkPeriod: number;
};
diff --git a/frontend/utils/service.ts b/frontend/utils/service.ts
index 5a957ce93..e9720408f 100644
--- a/frontend/utils/service.ts
+++ b/frontend/utils/service.ts
@@ -1,21 +1,22 @@
import { ServiceTemplate } from '@/client';
-import { StakingProgram } from '@/enums/StakingProgram';
+import { StakingProgramId } from '@/enums/StakingProgram';
/** TODO: update from hardcoded, workaround for quick release */
export const getMinimumStakedAmountRequired = (
- serviceTemplate: ServiceTemplate,
- stakingProgram: StakingProgram = StakingProgram.Beta,
-) => {
- // const olasCostOfBond = Number(
- // formatUnits(
- // `${serviceTemplate.configurations[CHAINS.GNOSIS.chainId].cost_of_bond}`,
- // 18,
- // ),
- // );
-
- if (stakingProgram === StakingProgram.Alpha) {
+ serviceTemplate?: ServiceTemplate, //TODO: remove, as unused
+ stakingProgramId: StakingProgramId = StakingProgramId.Beta,
+): number | undefined => {
+ if (stakingProgramId === StakingProgramId.Alpha) {
return 20;
}
- return 40;
+ if (stakingProgramId === StakingProgramId.Beta) {
+ return 40;
+ }
+
+ if (stakingProgramId === StakingProgramId.Beta2) {
+ return 100;
+ }
+
+ return;
};
diff --git a/operate/cli.py b/operate/cli.py
index 99cabe0f1..2c491ad3b 100644
--- a/operate/cli.py
+++ b/operate/cli.py
@@ -143,17 +143,22 @@ def create_app( # pylint: disable=too-many-locals, unused-argument, too-many-st
home: t.Optional[Path] = None,
) -> FastAPI:
"""Create FastAPI object."""
+ HEALTH_CHECKER_OFF = os.environ.get("HEALTH_CHECKER_OFF", "0") == "1"
+ number_of_fails = int(os.environ.get("HEALTH_CHECKER_TRIES", "5"))
logger = setup_logger(name="operate")
+ if HEALTH_CHECKER_OFF:
+ logger.warning("healthchecker is off!!!")
operate = OperateApp(home=home, logger=logger)
funding_jobs: t.Dict[str, asyncio.Task] = {}
- health_checker = HealthChecker(operate.service_manager())
+ health_checker = HealthChecker(
+ operate.service_manager(), number_of_fails=number_of_fails
+ )
# Create shutdown endpoint
shutdown_endpoint = uuid.uuid4().hex
(operate._path / "operate.kill").write_text( # pylint: disable=protected-access
shutdown_endpoint
)
-
thread_pool_executor = ThreadPoolExecutor()
async def run_in_executor(fn: t.Callable, *args: t.Any) -> t.Any:
@@ -188,7 +193,9 @@ def schedule_healthcheck_job(
service: str,
) -> None:
"""Schedule a healthcheck job."""
- health_checker.start_for_service(service)
+ if not HEALTH_CHECKER_OFF:
+ # dont start health checker if it's switched off
+ health_checker.start_for_service(service)
def cancel_funding_job(service: str) -> None:
"""Cancel funding job."""
diff --git a/operate/ledger/__init__.py b/operate/ledger/__init__.py
index 078a93d1e..c54609833 100644
--- a/operate/ledger/__init__.py
+++ b/operate/ledger/__init__.py
@@ -38,6 +38,7 @@
GOERLI_RPC = os.environ.get("DEV_RPC", "https://ethereum-goerli.publicnode.com")
SOLANA_RPC = os.environ.get("DEV_RPC", "https://api.mainnet-beta.solana.com")
+
PUBLIC_RPCS = {
ChainType.ETHEREUM: ETHEREUM_PUBLIC_RPC,
ChainType.GNOSIS: GNOSIS_PUBLIC_RPC,
diff --git a/operate/ledger/profiles.py b/operate/ledger/profiles.py
index bf7fa8433..523c1fdb9 100644
--- a/operate/ledger/profiles.py
+++ b/operate/ledger/profiles.py
@@ -39,6 +39,7 @@
ChainType.GNOSIS: {
"pearl_alpha": "0xEE9F19b5DF06c7E8Bfc7B28745dcf944C504198A",
"pearl_beta": "0xeF44Fb0842DDeF59D37f85D61A1eF492bbA6135d",
+ "pearl_beta_2": "0x1c2F82413666d2a3fD8bC337b0268e62dDF67434",
}
}
diff --git a/operate/services/deployment_runner.py b/operate/services/deployment_runner.py
index 1bf81904e..b53f9b12e 100644
--- a/operate/services/deployment_runner.py
+++ b/operate/services/deployment_runner.py
@@ -22,7 +22,6 @@
import os
import platform
import shutil # nosec
-import signal # nosec
import subprocess # nosec
import sys # nosec
import time
@@ -55,7 +54,6 @@ def stop(self) -> None:
def _kill_process(pid: int) -> None:
"""Kill process."""
- print(f"Trying to kill process: {pid}")
while True:
if not psutil.pid_exists(pid=pid):
return
@@ -66,14 +64,7 @@ def _kill_process(pid: int) -> None:
):
return
try:
- os.kill(
- pid,
- (
- signal.CTRL_C_EVENT # type: ignore
- if platform.platform() == "Windows"
- else signal.SIGKILL
- ),
- )
+ process.kill()
except OSError:
return
time.sleep(1)
@@ -236,14 +227,15 @@ def _start_agent(self) -> None:
"""Start agent process."""
working_dir = self._work_directory
env = json.loads((working_dir / "agent.json").read_text(encoding="utf-8"))
+ env = {**os.environ, **env}
process = subprocess.Popen( # pylint: disable=consider-using-with # nosec
args=[self._aea_bin, "run"],
cwd=working_dir / "agent",
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
- env={**os.environ, **env},
+ env=env,
creationflags=(
- 0x00000008 if platform.system() == "Windows" else 0
+ 0x00000200 if platform.system() == "Windows" else 0
), # Detach process from the main process
)
(working_dir / "agent.pid").write_text(
@@ -255,15 +247,24 @@ def _start_tendermint(self) -> None:
"""Start tendermint process."""
working_dir = self._work_directory
env = json.loads((working_dir / "tendermint.json").read_text(encoding="utf-8"))
+ env = {
+ **os.environ,
+ **env,
+ }
+
+ if platform.system() == "Windows":
+ # to look up for bundled in tendermint.exe
+ env["PATH"] = os.environ["PATH"] + ";" + os.path.dirname(sys.executable)
+
tendermint_com = self._tendermint_bin # type: ignore # pylint: disable=protected-access
process = subprocess.Popen( # pylint: disable=consider-using-with # nosec
args=[tendermint_com],
cwd=working_dir,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
- env={**os.environ, **env},
+ env=env,
creationflags=(
- 0x00000008 if platform.system() == "Windows" else 0
+ 0x00000200 if platform.system() == "Windows" else 0
), # Detach process from the main process
)
(working_dir / "tendermint.pid").write_text(
@@ -272,6 +273,25 @@ def _start_tendermint(self) -> None:
)
+class PyInstallerHostDeploymentRunnerMac(PyInstallerHostDeploymentRunner):
+ """Mac deployment runner."""
+
+
+class PyInstallerHostDeploymentRunnerWindows(PyInstallerHostDeploymentRunner):
+ """Windows deployment runner."""
+
+ @property
+ def _aea_bin(self) -> str:
+ """Return aea_bin path."""
+ abin = str(Path(sys._MEIPASS) / "aea_win.exe") # type: ignore # pylint: disable=protected-access
+ return abin
+
+ @property
+ def _tendermint_bin(self) -> str:
+ """Return tendermint path."""
+ return str(Path(sys._MEIPASS) / "tendermint_win.exe") # type: ignore # pylint: disable=protected-access
+
+
class HostPythonHostDeploymentRunner(BaseDeploymentRunner):
"""Deployment runner for host installed python."""
@@ -368,8 +388,15 @@ def _setup_agent(self) -> None:
def _get_host_deployment_runner(build_dir: Path) -> BaseDeploymentRunner:
"""Return depoyment runner according to running env."""
deployment_runner: BaseDeploymentRunner
+
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
- deployment_runner = PyInstallerHostDeploymentRunner(build_dir)
+ # pyinstaller inside!
+ if platform.system() == "Darwin":
+ deployment_runner = PyInstallerHostDeploymentRunner(build_dir)
+ elif platform.system() == "Windows":
+ deployment_runner = PyInstallerHostDeploymentRunnerWindows(build_dir)
+ else:
+ raise ValueError(f"Platform not supported {platform.system()}")
else:
deployment_runner = HostPythonHostDeploymentRunner(build_dir)
return deployment_runner
diff --git a/operate/services/health_checker.py b/operate/services/health_checker.py
index e1979be13..7a9c27373 100644
--- a/operate/services/health_checker.py
+++ b/operate/services/health_checker.py
@@ -34,19 +34,28 @@
class HealthChecker:
"""Health checker manager."""
- SLEEP_PERIOD = 30
- PORT_UP_TIMEOUT = 120 # seconds
+ SLEEP_PERIOD_DEFAULT = 30
+ PORT_UP_TIMEOUT_DEFAULT = 120 # seconds
+ NUMBER_OF_FAILS_DEFAULT = 5
- def __init__(self, service_manager: ServiceManager) -> None:
+ def __init__(
+ self,
+ service_manager: ServiceManager,
+ port_up_timeout: int | None = None,
+ sleep_period: int | None = None,
+ number_of_fails: int | None = None,
+ ) -> None:
"""Init the healtch checker."""
self._jobs: t.Dict[str, asyncio.Task] = {}
self.logger = setup_logger(name="operate.health_checker")
- self.logger.info("[HEALTCHECKER]: created")
self._service_manager = service_manager
+ self.port_up_timeout = port_up_timeout or self.PORT_UP_TIMEOUT_DEFAULT
+ self.sleep_period = sleep_period or self.SLEEP_PERIOD_DEFAULT
+ self.number_of_fails = number_of_fails or self.NUMBER_OF_FAILS_DEFAULT
def start_for_service(self, service: str) -> None:
"""Start for a specific service."""
- self.logger.info(f"[HEALTCHECKER]: Starting healthcheck job for {service}")
+ self.logger.info(f"[HEALTH_CHECKER]: Starting healthcheck job for {service}")
if service in self._jobs:
self.stop_for_service(service=service)
@@ -62,12 +71,12 @@ def stop_for_service(self, service: str) -> None:
if service not in self._jobs:
return
self.logger.info(
- f"[HEALTCHECKER]: Cancelling existing healthcheck_jobs job for {service}"
+ f"[HEALTH_CHECKER]: Cancelling existing healthcheck_jobs job for {service}"
)
status = self._jobs[service].cancel()
if not status:
self.logger.info(
- f"[HEALTCHECKER]: Healthcheck job cancellation for {service} failed"
+ f"[HEALTH_CHECKER]: Healthcheck job cancellation for {service} failed"
)
@staticmethod
@@ -90,22 +99,24 @@ async def healthcheck_job(
try:
self.logger.info(
- f"[HEALTCHECKER] Start healthcheck job for service: {service}"
+ f"[HEALTH_CHECKER] Start healthcheck job for service: {service}"
)
async def _wait_for_port(sleep_period: int = 15) -> None:
- self.logger.info("[HEALTCHECKER]: wait port is up")
+ self.logger.info("[HEALTH_CHECKER]: wait port is up")
while True:
try:
await self.check_service_health(service)
- self.logger.info("[HEALTCHECKER]: port is UP")
+ self.logger.info("[HEALTH_CHECKER]: port is UP")
return
except aiohttp.ClientConnectionError:
- self.logger.error("[HEALTCHECKER]: error connecting http port")
+ self.logger.error(
+ "[HEALTH_CHECKER]: error connecting http port"
+ )
await asyncio.sleep(sleep_period)
async def _check_port_ready(
- timeout: int = self.PORT_UP_TIMEOUT, sleep_period: int = 15
+ timeout: int = self.port_up_timeout, sleep_period: int = 15
) -> bool:
try:
await asyncio.wait_for(
@@ -116,7 +127,7 @@ async def _check_port_ready(
return False
async def _check_health(
- number_of_fails: int = 5, sleep_period: int = self.SLEEP_PERIOD
+ number_of_fails: int = 5, sleep_period: int = self.sleep_period
) -> None:
fails = 0
while True:
@@ -125,24 +136,24 @@ async def _check_health(
healthy = await self.check_service_health(service)
except aiohttp.ClientConnectionError:
self.logger.info(
- f"[HEALTCHECKER] {service} port read failed. restart"
+ f"[HEALTH_CHECKER] {service} port read failed. restart"
)
return
if not healthy:
fails += 1
self.logger.info(
- f"[HEALTCHECKER] {service} not healthy for {fails} time in a row"
+ f"[HEALTH_CHECKER] {service} not healthy for {fails} time in a row"
)
else:
- self.logger.info(f"[HEALTCHECKER] {service} is HEALTHY")
+ self.logger.info(f"[HEALTH_CHECKER] {service} is HEALTHY")
# reset fails if comes healty
fails = 0
if fails >= number_of_fails:
# too much fails, exit
self.logger.error(
- f"[HEALTCHECKER] {service} failed {fails} times in a row. restart"
+ f"[HEALTH_CHECKER] {service} failed {fails} times in a row. restart"
)
return
await asyncio.sleep(sleep_period)
@@ -162,17 +173,20 @@ def _do_restart() -> None:
# upper cycle
while True:
- self.logger.info(f"[HEALTCHECKER] {service} wait for port ready")
- if await _check_port_ready(timeout=self.PORT_UP_TIMEOUT):
+ self.logger.info(f"[HEALTH_CHECKER] {service} wait for port ready")
+ if await _check_port_ready(timeout=self.port_up_timeout):
# blocking till restart needed
self.logger.info(
- f"[HEALTCHECKER] {service} port is ready, checking health every {self.SLEEP_PERIOD}"
+ f"[HEALTH_CHECKER] {service} port is ready, checking health every {self.sleep_period}"
+ )
+ await _check_health(
+ number_of_fails=self.number_of_fails,
+ sleep_period=self.sleep_period,
)
- await _check_health(sleep_period=self.SLEEP_PERIOD)
else:
self.logger.info(
- "[HEALTCHECKER] port not ready within timeout. restart deployment"
+ "[HEALTH_CHECKER] port not ready within timeout. restart deployment"
)
# perform restart
diff --git a/operate/services/manage.py b/operate/services/manage.py
index 076701949..83ccb84e0 100644
--- a/operate/services/manage.py
+++ b/operate/services/manage.py
@@ -476,9 +476,6 @@ def _deploy_service_onchain_from_safe( # pylint: disable=too-many-statements,to
# TODO fix this
os.environ["CUSTOM_CHAIN_RPC"] = ledger_config.rpc
- os.environ[
- "OPEN_AUTONOMY_SUBGRAPH_URL"
- ] = "https://subgraph.autonolas.tech/subgraphs/name/autonolas-staging"
current_agent_id = None
if chain_data.token > -1:
@@ -497,16 +494,25 @@ def _deploy_service_onchain_from_safe( # pylint: disable=too-many-statements,to
user_params.staking_program_id
],
)
- else: # TODO fix this - using pearl beta params
+ else:
staking_params = dict( # nosec
+ staking_contract=NULL_ADDRESS,
agent_ids=[25],
service_registry="0x9338b5153AE39BB89f50468E608eD9d764B755fD", # nosec
- staking_token="0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f", # nosec
+ staking_token=NULL_ADDRESS, # nosec
service_registry_token_utility="0xa45E64d13A30a51b91ae0eb182e88a40e9b18eD8", # nosec
min_staking_deposit=20000000000000000000,
- activity_checker="0x155547857680A6D51bebC5603397488988DEb1c8", # nosec
+ activity_checker=NULL_ADDRESS, # nosec
+ agent_mech="0x77af31De935740567Cf4fF1986D04B2c964A786a", # nosec
)
+ # Override service.yaml variables for the deployment
+ os.environ["STAKING_CONTRACT_ADDRESS"] = staking_params["staking_contract"]
+ os.environ["MECH_ACTIVITY_CHECKER_CONTRACT"] = staking_params[
+ "activity_checker"
+ ]
+ os.environ["MECH_CONTRACT_ADDRESS"] = staking_params["agent_mech"]
+
if user_params.use_staking:
self.logger.info("Checking staking compatibility")
@@ -541,9 +547,10 @@ def _deploy_service_onchain_from_safe( # pylint: disable=too-many-statements,to
)
on_chain_hash = self._get_on_chain_hash(chain_config=chain_config)
- current_agent_bond = staking_params[
- "min_staking_deposit"
- ] # TODO fixme, read from service registry token utility contract
+ current_agent_bond = sftxb.get_agent_bond(
+ service_id=chain_data.token, agent_id=staking_params["agent_ids"][0]
+ )
+
is_first_mint = (
self._get_on_chain_state(service=service, chain_id=chain_id)
== OnChainState.NON_EXISTENT
@@ -552,8 +559,9 @@ def _deploy_service_onchain_from_safe( # pylint: disable=too-many-statements,to
(not is_first_mint)
and (on_chain_hash is not None)
and (
- on_chain_hash != service.hash
- or current_agent_id != staking_params["agent_ids"][0]
+ # TODO Discuss how to manage on-chain hash updates with staking programs.
+ # on_chain_hash != service.hash or # noqa
+ current_agent_id != staking_params["agent_ids"][0]
or current_agent_bond != staking_params["min_staking_deposit"]
)
)
@@ -561,12 +569,15 @@ def _deploy_service_onchain_from_safe( # pylint: disable=too-many-statements,to
chain_data, ledger_config, sftxb
)
+ self.logger.info(f"{chain_data.token=}")
self.logger.info(f"{current_staking_program=}")
self.logger.info(f"{user_params.staking_program_id=}")
self.logger.info(f"{on_chain_hash=}")
self.logger.info(f"{service.hash=}")
self.logger.info(f"{current_agent_id=}")
self.logger.info(f"{staking_params['agent_ids'][0]=}")
+ self.logger.info(f"{current_agent_bond=}")
+ self.logger.info(f"{staking_params['min_staking_deposit']=}")
self.logger.info(f"{is_first_mint=}")
self.logger.info(f"{is_update=}")
diff --git a/operate/services/protocol.py b/operate/services/protocol.py
index 5b122bb7e..1d5b28536 100644
--- a/operate/services/protocol.py
+++ b/operate/services/protocol.py
@@ -48,6 +48,7 @@
get_delployment_payload,
get_reuse_multisig_payload,
get_service_info,
+ get_token_deposit_amount,
)
from autonomy.chain.tx import TxSettler
from autonomy.cli.helpers.chain import MintHelper as MintManager
@@ -572,6 +573,24 @@ def info(self, token_id: int) -> t.Dict:
instances=instances,
)
+ def get_agent_bond(self, service_id: int, agent_id: int) -> int:
+ """Get the agent bond for a given service"""
+ self._patch()
+
+ if service_id <= 0 or agent_id <= 0:
+ return 0
+
+ ledger_api, _ = OnChainHelper.get_ledger_and_crypto_objects(
+ chain_type=self.chain_type
+ )
+ bond = get_token_deposit_amount(
+ ledger_api=ledger_api,
+ chain_type=self.chain_type,
+ service_id=service_id,
+ agent_id=agent_id,
+ )
+ return bond
+
def get_service_safe_owners(self, service_id: int) -> t.List[str]:
"""Get list of owners."""
ledger_api, _ = OnChainHelper.get_ledger_and_crypto_objects(
@@ -749,13 +768,18 @@ def get_staking_params(self, staking_contract: str) -> t.Dict:
staking_contract=staking_contract,
)
+ # TODO Read from activity checker contract
+ agent_mech = "0x77af31De935740567Cf4fF1986D04B2c964A786a" # nosec
+
return dict(
+ staking_contract=staking_contract,
agent_ids=agent_ids,
service_registry=service_registry,
staking_token=staking_token,
service_registry_token_utility=service_registry_token_utility,
min_staking_deposit=min_staking_deposit,
activity_checker=activity_checker,
+ agent_mech=agent_mech,
)
diff --git a/operate/services/service.py b/operate/services/service.py
index 7e115f5ff..ab2d26315 100644
--- a/operate/services/service.py
+++ b/operate/services/service.py
@@ -21,8 +21,10 @@
import json
import os
+import platform
import shutil
import subprocess # nosec
+import sys
import typing as t
from copy import copy, deepcopy
from dataclasses import dataclass
@@ -272,11 +274,17 @@ class HostDeploymentGenerator(BaseDeploymentGenerator):
def generate_config_tendermint(self) -> "HostDeploymentGenerator":
"""Generate tendermint configuration."""
tmhome = str(self.build_dir / "node")
+ tendermint_executable = str(
+ shutil.which("tendermint"),
+ )
+ # TODO: move all platform related things to a dedicated file
+ if platform.system() == "Windows":
+ tendermint_executable = str(
+ Path(os.path.dirname(sys.executable)) / "tendermint.exe"
+ )
subprocess.run( # pylint: disable=subprocess-run-check # nosec
args=[
- str(
- shutil.which("tendermint"),
- ),
+ tendermint_executable,
"--home",
tmhome,
"init",
diff --git a/package.json b/package.json
index f940d09a7..923160d70 100644
--- a/package.json
+++ b/package.json
@@ -58,5 +58,5 @@
"download-binaries": "sh download_binaries.sh",
"build:pearl": "sh build_pearl.sh"
},
- "version": "0.1.0-rc120"
+ "version": "0.1.0-rc127"
}
\ No newline at end of file
diff --git a/poetry.lock b/poetry.lock
index fd3b19a72..5fce400d8 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
[[package]]
name = "aiohttp"
@@ -178,22 +178,22 @@ files = [
[[package]]
name = "attrs"
-version = "23.2.0"
+version = "24.2.0"
description = "Classes Without Boilerplate"
optional = false
python-versions = ">=3.7"
files = [
- {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
- {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
+ {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
+ {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
]
[package.extras]
-cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
-dev = ["attrs[tests]", "pre-commit"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
-tests = ["attrs[tests-no-zope]", "zope-interface"]
-tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
-tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
+benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
[[package]]
name = "backoff"
@@ -404,74 +404,89 @@ files = [
[[package]]
name = "certifi"
-version = "2024.7.4"
+version = "2024.8.30"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
- {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"},
- {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"},
+ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
+ {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
]
[[package]]
name = "cffi"
-version = "1.16.0"
+version = "1.17.0"
description = "Foreign Function Interface for Python calling C code."
optional = false
python-versions = ">=3.8"
files = [
- {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
- {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
- {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
- {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
- {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
- {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
- {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
- {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
- {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
- {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
- {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
- {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
- {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
- {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
- {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
- {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
- {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
- {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"},
- {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"},
- {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"},
- {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
- {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
- {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
- {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
- {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
- {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
- {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
+ {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"},
+ {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"},
+ {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"},
+ {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"},
+ {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"},
+ {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"},
+ {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"},
+ {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"},
+ {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"},
+ {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"},
+ {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"},
+ {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"},
+ {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"},
+ {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"},
+ {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"},
+ {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"},
+ {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"},
+ {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"},
+ {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"},
+ {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"},
+ {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"},
+ {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"},
+ {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"},
+ {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"},
+ {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"},
+ {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"},
+ {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"},
+ {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"},
+ {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"},
+ {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"},
+ {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"},
+ {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"},
+ {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"},
+ {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"},
+ {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"},
+ {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"},
+ {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"},
+ {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"},
+ {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"},
+ {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"},
+ {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"},
+ {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"},
+ {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"},
+ {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"},
+ {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"},
+ {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"},
+ {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"},
+ {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"},
+ {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"},
+ {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"},
+ {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"},
+ {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"},
+ {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"},
+ {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"},
+ {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"},
+ {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"},
+ {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"},
+ {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"},
+ {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"},
+ {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"},
+ {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"},
+ {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"},
+ {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"},
+ {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"},
+ {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"},
+ {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"},
+ {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"},
]
[package.dependencies]
@@ -694,63 +709,83 @@ requests = "*"
[[package]]
name = "coverage"
-version = "7.6.0"
+version = "7.6.1"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"},
- {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"},
- {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"},
- {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"},
- {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"},
- {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"},
- {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"},
- {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"},
- {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"},
- {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"},
- {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"},
- {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"},
- {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"},
- {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"},
- {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"},
- {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"},
- {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"},
- {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"},
- {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"},
- {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"},
- {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"},
- {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"},
- {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"},
- {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"},
- {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"},
- {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"},
- {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"},
- {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"},
- {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"},
- {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"},
- {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"},
- {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"},
- {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"},
- {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"},
- {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"},
- {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"},
- {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"},
- {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"},
- {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"},
- {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"},
- {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"},
- {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"},
- {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"},
- {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"},
- {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"},
- {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"},
- {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"},
- {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"},
- {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"},
- {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"},
- {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"},
- {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"},
+ {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"},
+ {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"},
+ {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"},
+ {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"},
+ {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"},
+ {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"},
+ {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"},
+ {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"},
+ {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"},
+ {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"},
+ {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"},
+ {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"},
+ {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"},
+ {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"},
+ {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"},
+ {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"},
+ {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"},
+ {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"},
+ {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"},
+ {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"},
+ {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"},
+ {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"},
+ {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"},
+ {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"},
+ {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"},
+ {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"},
+ {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"},
+ {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"},
+ {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"},
+ {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"},
+ {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"},
+ {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"},
+ {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"},
+ {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"},
+ {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"},
+ {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"},
+ {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"},
+ {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"},
+ {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"},
+ {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"},
+ {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"},
+ {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"},
+ {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"},
+ {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"},
+ {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"},
+ {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"},
+ {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"},
+ {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"},
+ {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"},
+ {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"},
+ {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"},
+ {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"},
+ {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"},
+ {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"},
+ {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"},
+ {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"},
+ {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"},
+ {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"},
+ {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"},
+ {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"},
+ {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"},
+ {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"},
+ {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"},
+ {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"},
+ {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"},
+ {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"},
+ {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"},
+ {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"},
+ {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"},
+ {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"},
+ {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"},
+ {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"},
]
[package.extras]
@@ -758,38 +793,38 @@ toml = ["tomli"]
[[package]]
name = "cryptography"
-version = "43.0.0"
+version = "43.0.1"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = ">=3.7"
files = [
- {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"},
- {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"},
- {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"},
- {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"},
- {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"},
- {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"},
- {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"},
- {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"},
- {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"},
- {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"},
- {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"},
- {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"},
- {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"},
- {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"},
- {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"},
- {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"},
- {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"},
- {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"},
- {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"},
- {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"},
- {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"},
- {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"},
- {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"},
- {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"},
- {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"},
- {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"},
- {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"},
+ {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"},
+ {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"},
+ {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"},
+ {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"},
+ {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"},
+ {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"},
+ {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"},
+ {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"},
+ {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"},
+ {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"},
+ {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"},
+ {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"},
+ {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"},
+ {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"},
+ {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"},
+ {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"},
+ {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"},
+ {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"},
+ {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"},
+ {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"},
+ {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"},
+ {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"},
+ {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"},
+ {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"},
+ {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"},
+ {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"},
+ {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"},
]
[package.dependencies]
@@ -802,7 +837,7 @@ nox = ["nox"]
pep8test = ["check-sdist", "click", "mypy", "ruff"]
sdist = ["build"]
ssh = ["bcrypt (>=3.1.5)"]
-test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
+test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
test-randomorder = ["pytest-randomly"]
[[package]]
@@ -1347,13 +1382,13 @@ files = [
[[package]]
name = "googleapis-common-protos"
-version = "1.63.2"
+version = "1.65.0"
description = "Common protobufs used in Google APIs"
optional = false
python-versions = ">=3.7"
files = [
- {file = "googleapis-common-protos-1.63.2.tar.gz", hash = "sha256:27c5abdffc4911f28101e635de1533fb4cfd2c37fbaa9174587c799fac90aa87"},
- {file = "googleapis_common_protos-1.63.2-py2.py3-none-any.whl", hash = "sha256:27a2499c7e8aff199665b22741997e485eccc8645aa9176c7c988e6fae507945"},
+ {file = "googleapis_common_protos-1.65.0-py2.py3-none-any.whl", hash = "sha256:2972e6c496f435b92590fd54045060867f3fe9be2c82ab148fc8885035479a63"},
+ {file = "googleapis_common_protos-1.65.0.tar.gz", hash = "sha256:334a29d07cddc3aa01dee4988f9afd9b2916ee2ff49d6b757155dc0d197852c0"},
]
[package.dependencies]
@@ -1403,61 +1438,61 @@ files = [
[[package]]
name = "grpcio"
-version = "1.65.1"
+version = "1.66.1"
description = "HTTP/2-based RPC framework"
optional = false
python-versions = ">=3.8"
files = [
- {file = "grpcio-1.65.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:3dc5f928815b8972fb83b78d8db5039559f39e004ec93ebac316403fe031a062"},
- {file = "grpcio-1.65.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:8333ca46053c35484c9f2f7e8d8ec98c1383a8675a449163cea31a2076d93de8"},
- {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:7af64838b6e615fff0ec711960ed9b6ee83086edfa8c32670eafb736f169d719"},
- {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb64b4166362d9326f7efbf75b1c72106c1aa87f13a8c8b56a1224fac152f5c"},
- {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8422dc13ad93ec8caa2612b5032a2b9cd6421c13ed87f54db4a3a2c93afaf77"},
- {file = "grpcio-1.65.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4effc0562b6c65d4add6a873ca132e46ba5e5a46f07c93502c37a9ae7f043857"},
- {file = "grpcio-1.65.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a6c71575a2fedf259724981fd73a18906513d2f306169c46262a5bae956e6364"},
- {file = "grpcio-1.65.1-cp310-cp310-win32.whl", hash = "sha256:34966cf526ef0ea616e008d40d989463e3db157abb213b2f20c6ce0ae7928875"},
- {file = "grpcio-1.65.1-cp310-cp310-win_amd64.whl", hash = "sha256:ca931de5dd6d9eb94ff19a2c9434b23923bce6f767179fef04dfa991f282eaad"},
- {file = "grpcio-1.65.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:bbb46330cc643ecf10bd9bd4ca8e7419a14b6b9dedd05f671c90fb2c813c6037"},
- {file = "grpcio-1.65.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d827a6fb9215b961eb73459ad7977edb9e748b23e3407d21c845d1d8ef6597e5"},
- {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:6e71aed8835f8d9fbcb84babc93a9da95955d1685021cceb7089f4f1e717d719"},
- {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1c84560b3b2d34695c9ba53ab0264e2802721c530678a8f0a227951f453462"},
- {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27adee2338d697e71143ed147fe286c05810965d5d30ec14dd09c22479bfe48a"},
- {file = "grpcio-1.65.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f62652ddcadc75d0e7aa629e96bb61658f85a993e748333715b4ab667192e4e8"},
- {file = "grpcio-1.65.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:71a05fd814700dd9cb7d9a507f2f6a1ef85866733ccaf557eedacec32d65e4c2"},
- {file = "grpcio-1.65.1-cp311-cp311-win32.whl", hash = "sha256:b590f1ad056294dfaeac0b7e1b71d3d5ace638d8dd1f1147ce4bd13458783ba8"},
- {file = "grpcio-1.65.1-cp311-cp311-win_amd64.whl", hash = "sha256:12e9bdf3b5fd48e5fbe5b3da382ad8f97c08b47969f3cca81dd9b36b86ed39e2"},
- {file = "grpcio-1.65.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:54cb822e177374b318b233e54b6856c692c24cdbd5a3ba5335f18a47396bac8f"},
- {file = "grpcio-1.65.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:aaf3c54419a28d45bd1681372029f40e5bfb58e5265e3882eaf21e4a5f81a119"},
- {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:557de35bdfbe8bafea0a003dbd0f4da6d89223ac6c4c7549d78e20f92ead95d9"},
- {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8bfd95ef3b097f0cc86ade54eafefa1c8ed623aa01a26fbbdcd1a3650494dd11"},
- {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e6a8f3d6c41e6b642870afe6cafbaf7b61c57317f9ec66d0efdaf19db992b90"},
- {file = "grpcio-1.65.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1faaf7355ceed07ceaef0b9dcefa4c98daf1dd8840ed75c2de128c3f4a4d859d"},
- {file = "grpcio-1.65.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:60f1f38eed830488ad2a1b11579ef0f345ff16fffdad1d24d9fbc97ba31804ff"},
- {file = "grpcio-1.65.1-cp312-cp312-win32.whl", hash = "sha256:e75acfa52daf5ea0712e8aa82f0003bba964de7ae22c26d208cbd7bc08500177"},
- {file = "grpcio-1.65.1-cp312-cp312-win_amd64.whl", hash = "sha256:ff5a84907e51924973aa05ed8759210d8cdae7ffcf9e44fd17646cf4a902df59"},
- {file = "grpcio-1.65.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:1fbd6331f18c3acd7e09d17fd840c096f56eaf0ef830fbd50af45ae9dc8dfd83"},
- {file = "grpcio-1.65.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:de5b6be29116e094c5ef9d9e4252e7eb143e3d5f6bd6d50a78075553ab4930b0"},
- {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:e4a3cdba62b2d6aeae6027ae65f350de6dc082b72e6215eccf82628e79efe9ba"},
- {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941c4869aa229d88706b78187d60d66aca77fe5c32518b79e3c3e03fc26109a2"},
- {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40cebe5edb518d78b8131e87cb83b3ee688984de38a232024b9b44e74ee53d3"},
- {file = "grpcio-1.65.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2ca684ba331fb249d8a1ce88db5394e70dbcd96e58d8c4b7e0d7b141a453dce9"},
- {file = "grpcio-1.65.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8558f0083ddaf5de64a59c790bffd7568e353914c0c551eae2955f54ee4b857f"},
- {file = "grpcio-1.65.1-cp38-cp38-win32.whl", hash = "sha256:8d8143a3e3966f85dce6c5cc45387ec36552174ba5712c5dc6fcc0898fb324c0"},
- {file = "grpcio-1.65.1-cp38-cp38-win_amd64.whl", hash = "sha256:76e81a86424d6ca1ce7c16b15bdd6a964a42b40544bf796a48da241fdaf61153"},
- {file = "grpcio-1.65.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb5175f45c980ff418998723ea1b3869cce3766d2ab4e4916fbd3cedbc9d0ed3"},
- {file = "grpcio-1.65.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b12c1aa7b95abe73b3e04e052c8b362655b41c7798da69f1eaf8d186c7d204df"},
- {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:3019fb50128b21a5e018d89569ffaaaa361680e1346c2f261bb84a91082eb3d3"},
- {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ae15275ed98ea267f64ee9ddedf8ecd5306a5b5bb87972a48bfe24af24153e8"},
- {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f096ffb881f37e8d4f958b63c74bfc400c7cebd7a944b027357cd2fb8d91a57"},
- {file = "grpcio-1.65.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2f56b5a68fdcf17a0a1d524bf177218c3c69b3947cb239ea222c6f1867c3ab68"},
- {file = "grpcio-1.65.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:941596d419b9736ab548aa0feb5bbba922f98872668847bf0720b42d1d227b9e"},
- {file = "grpcio-1.65.1-cp39-cp39-win32.whl", hash = "sha256:5fd7337a823b890215f07d429f4f193d24b80d62a5485cf88ee06648591a0c57"},
- {file = "grpcio-1.65.1-cp39-cp39-win_amd64.whl", hash = "sha256:1bceeec568372cbebf554eae1b436b06c2ff24cfaf04afade729fb9035408c6c"},
- {file = "grpcio-1.65.1.tar.gz", hash = "sha256:3c492301988cd720cd145d84e17318d45af342e29ef93141228f9cd73222368b"},
+ {file = "grpcio-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:4877ba180591acdf127afe21ec1c7ff8a5ecf0fe2600f0d3c50e8c4a1cbc6492"},
+ {file = "grpcio-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3750c5a00bd644c75f4507f77a804d0189d97a107eb1481945a0cf3af3e7a5ac"},
+ {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a013c5fbb12bfb5f927444b477a26f1080755a931d5d362e6a9a720ca7dbae60"},
+ {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1b24c23d51a1e8790b25514157d43f0a4dce1ac12b3f0b8e9f66a5e2c4c132f"},
+ {file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7ffb8ea674d68de4cac6f57d2498fef477cef582f1fa849e9f844863af50083"},
+ {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:307b1d538140f19ccbd3aed7a93d8f71103c5d525f3c96f8616111614b14bf2a"},
+ {file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c17ebcec157cfb8dd445890a03e20caf6209a5bd4ac5b040ae9dbc59eef091d"},
+ {file = "grpcio-1.66.1-cp310-cp310-win32.whl", hash = "sha256:ef82d361ed5849d34cf09105d00b94b6728d289d6b9235513cb2fcc79f7c432c"},
+ {file = "grpcio-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:292a846b92cdcd40ecca46e694997dd6b9be6c4c01a94a0dfb3fcb75d20da858"},
+ {file = "grpcio-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:c30aeceeaff11cd5ddbc348f37c58bcb96da8d5aa93fed78ab329de5f37a0d7a"},
+ {file = "grpcio-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8a1e224ce6f740dbb6b24c58f885422deebd7eb724aff0671a847f8951857c26"},
+ {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a66fe4dc35d2330c185cfbb42959f57ad36f257e0cc4557d11d9f0a3f14311df"},
+ {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ba04659e4fce609de2658fe4dbf7d6ed21987a94460f5f92df7579fd5d0e22"},
+ {file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4573608e23f7e091acfbe3e84ac2045680b69751d8d67685ffa193a4429fedb1"},
+ {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7e06aa1f764ec8265b19d8f00140b8c4b6ca179a6dc67aa9413867c47e1fb04e"},
+ {file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3885f037eb11f1cacc41f207b705f38a44b69478086f40608959bf5ad85826dd"},
+ {file = "grpcio-1.66.1-cp311-cp311-win32.whl", hash = "sha256:97ae7edd3f3f91480e48ede5d3e7d431ad6005bfdbd65c1b56913799ec79e791"},
+ {file = "grpcio-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:cfd349de4158d797db2bd82d2020554a121674e98fbe6b15328456b3bf2495bb"},
+ {file = "grpcio-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:a92c4f58c01c77205df6ff999faa008540475c39b835277fb8883b11cada127a"},
+ {file = "grpcio-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fdb14bad0835914f325349ed34a51940bc2ad965142eb3090081593c6e347be9"},
+ {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f03a5884c56256e08fd9e262e11b5cfacf1af96e2ce78dc095d2c41ccae2c80d"},
+ {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ca2559692d8e7e245d456877a85ee41525f3ed425aa97eb7a70fc9a79df91a0"},
+ {file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ca1be089fb4446490dd1135828bd42a7c7f8421e74fa581611f7afdf7ab761"},
+ {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d639c939ad7c440c7b2819a28d559179a4508783f7e5b991166f8d7a34b52815"},
+ {file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b9feb4e5ec8dc2d15709f4d5fc367794d69277f5d680baf1910fc9915c633524"},
+ {file = "grpcio-1.66.1-cp312-cp312-win32.whl", hash = "sha256:7101db1bd4cd9b880294dec41a93fcdce465bdbb602cd8dc5bd2d6362b618759"},
+ {file = "grpcio-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:b0aa03d240b5539648d996cc60438f128c7f46050989e35b25f5c18286c86734"},
+ {file = "grpcio-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:ecfe735e7a59e5a98208447293ff8580e9db1e890e232b8b292dc8bd15afc0d2"},
+ {file = "grpcio-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4825a3aa5648010842e1c9d35a082187746aa0cdbf1b7a2a930595a94fb10fce"},
+ {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f517fd7259fe823ef3bd21e508b653d5492e706e9f0ef82c16ce3347a8a5620c"},
+ {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1fe60d0772831d96d263b53d83fb9a3d050a94b0e94b6d004a5ad111faa5b5b"},
+ {file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31a049daa428f928f21090403e5d18ea02670e3d5d172581670be006100db9ef"},
+ {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f914386e52cbdeb5d2a7ce3bf1fdfacbe9d818dd81b6099a05b741aaf3848bb"},
+ {file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bff2096bdba686019fb32d2dde45b95981f0d1490e054400f70fc9a8af34b49d"},
+ {file = "grpcio-1.66.1-cp38-cp38-win32.whl", hash = "sha256:aa8ba945c96e73de29d25331b26f3e416e0c0f621e984a3ebdb2d0d0b596a3b3"},
+ {file = "grpcio-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:161d5c535c2bdf61b95080e7f0f017a1dfcb812bf54093e71e5562b16225b4ce"},
+ {file = "grpcio-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:d0cd7050397b3609ea51727b1811e663ffda8bda39c6a5bb69525ef12414b503"},
+ {file = "grpcio-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0e6c9b42ded5d02b6b1fea3a25f036a2236eeb75d0579bfd43c0018c88bf0a3e"},
+ {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c9f80f9fad93a8cf71c7f161778ba47fd730d13a343a46258065c4deb4b550c0"},
+ {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dd67ed9da78e5121efc5c510f0122a972216808d6de70953a740560c572eb44"},
+ {file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48b0d92d45ce3be2084b92fb5bae2f64c208fea8ceed7fccf6a7b524d3c4942e"},
+ {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d813316d1a752be6f5c4360c49f55b06d4fe212d7df03253dfdae90c8a402bb"},
+ {file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c9bebc6627873ec27a70fc800f6083a13c70b23a5564788754b9ee52c5aef6c"},
+ {file = "grpcio-1.66.1-cp39-cp39-win32.whl", hash = "sha256:30a1c2cf9390c894c90bbc70147f2372130ad189cffef161f0432d0157973f45"},
+ {file = "grpcio-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:17663598aadbedc3cacd7bbde432f541c8e07d2496564e22b214b22c7523dac8"},
+ {file = "grpcio-1.66.1.tar.gz", hash = "sha256:35334f9c9745add3e357e3372756fd32d925bd52c41da97f4dfdafbde0bf0ee2"},
]
[package.extras]
-protobuf = ["grpcio-tools (>=1.65.1)"]
+protobuf = ["grpcio-tools (>=1.66.1)"]
[[package]]
name = "h11"
@@ -1489,24 +1524,24 @@ test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>=
[[package]]
name = "idna"
-version = "3.7"
+version = "3.8"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
files = [
- {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
- {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
+ {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"},
+ {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"},
]
[[package]]
name = "importlib-metadata"
-version = "8.2.0"
+version = "8.4.0"
description = "Read metadata from Python packages"
optional = false
python-versions = ">=3.8"
files = [
- {file = "importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369"},
- {file = "importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d"},
+ {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"},
+ {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"},
]
[package.dependencies]
@@ -1936,7 +1971,10 @@ py-multicodec = ">=0.2.0"
pymultihash = "0.8.2"
pytest = {version = ">=7.0.0,<7.3.0", optional = true, markers = "extra == \"all\""}
python-dotenv = ">=0.14.0,<1.0.1"
-pyyaml = {version = ">=6.0.1,<7", optional = true, markers = "extra == \"all\""}
+pyyaml = [
+ {version = ">=6.0.1,<7"},
+ {version = ">=6.0.1,<9", optional = true, markers = "extra == \"all\""},
+]
requests = ">=2.28.1,<3"
semver = ">=2.9.1,<3.0.0"
@@ -2076,13 +2114,13 @@ files = [
[[package]]
name = "paramiko"
-version = "3.4.0"
+version = "3.4.1"
description = "SSH2 protocol library"
optional = false
python-versions = ">=3.6"
files = [
- {file = "paramiko-3.4.0-py3-none-any.whl", hash = "sha256:43f0b51115a896f9c00f59618023484cb3a14b98bbceab43394a39c6739b7ee7"},
- {file = "paramiko-3.4.0.tar.gz", hash = "sha256:aac08f26a31dc4dffd92821527d1682d99d52f9ef6851968114a8728f3c274d3"},
+ {file = "paramiko-3.4.1-py3-none-any.whl", hash = "sha256:8e49fd2f82f84acf7ffd57c64311aa2b30e575370dc23bdb375b10262f7eac32"},
+ {file = "paramiko-3.4.1.tar.gz", hash = "sha256:8b15302870af7f6652f2e038975c1d2973f06046cb5d7d65355668b3ecbece0c"},
]
[package.dependencies]
@@ -2111,13 +2149,13 @@ regex = ">=2022.3.15"
[[package]]
name = "pefile"
-version = "2023.2.7"
+version = "2024.8.26"
description = "Python PE parsing module"
optional = false
python-versions = ">=3.6.0"
files = [
- {file = "pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"},
- {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"},
+ {file = "pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f"},
+ {file = "pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632"},
]
[[package]]
@@ -2418,23 +2456,23 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
[[package]]
name = "pyinstaller"
-version = "6.9.0"
+version = "6.10.0"
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
optional = false
-python-versions = "<3.13,>=3.8"
+python-versions = "<3.14,>=3.8"
files = [
- {file = "pyinstaller-6.9.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:5ced2e83acf222b936ea94abc5a5cc96588705654b39138af8fb321d9cf2b954"},
- {file = "pyinstaller-6.9.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:f18a3d551834ef8fb7830d48d4cc1527004d0e6b51ded7181e78374ad6111846"},
- {file = "pyinstaller-6.9.0-py3-none-manylinux2014_i686.whl", hash = "sha256:f2fc568de3d6d2a176716a3fc9f20da06d351e8bea5ddd10ecb5659fce3a05b0"},
- {file = "pyinstaller-6.9.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:a0f378f64ad0655d11ade9fde7877e7573fd3d5066231608ce7dfa9040faecdd"},
- {file = "pyinstaller-6.9.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:7bf0c13c5a8560c89540746ae742f4f4b82290e95a6b478374d9f34959fe25d6"},
- {file = "pyinstaller-6.9.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:da994aba14c5686db88796684de265a8665733b4df09b939f7ebdf097d18df72"},
- {file = "pyinstaller-6.9.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:4e3e50743c091a06e6d01c59bdd6d03967b453ee5384a9e790759be4129db4a4"},
- {file = "pyinstaller-6.9.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b041be2fe78da47a269604d62c940d68c62f9a3913bdf64af4123f7689d47099"},
- {file = "pyinstaller-6.9.0-py3-none-win32.whl", hash = "sha256:2bf4de17a1c63c0b797b38e13bfb4d03b5ee7c0a68e28b915a7eaacf6b76087f"},
- {file = "pyinstaller-6.9.0-py3-none-win_amd64.whl", hash = "sha256:43709c70b1da8441a730327a8ed362bfcfdc3d42c1bf89f3e2b0a163cc4e7d33"},
- {file = "pyinstaller-6.9.0-py3-none-win_arm64.whl", hash = "sha256:f15c1ef11ed5ceb32447dfbdab687017d6adbef7fc32aa359d584369bfe56eda"},
- {file = "pyinstaller-6.9.0.tar.gz", hash = "sha256:f4a75c552facc2e2a370f1e422b971b5e5cdb4058ff38cea0235aa21fc0b378f"},
+ {file = "pyinstaller-6.10.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:d60fb22859e11483af735aec115fdde09467cdbb29edd9844839f2c920b748c0"},
+ {file = "pyinstaller-6.10.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:46d75359668993ddd98630a3669dc5249f3c446e35239b43bc7f4155bc574748"},
+ {file = "pyinstaller-6.10.0-py3-none-manylinux2014_i686.whl", hash = "sha256:3398a98fa17d47ccb31f8779ecbdacec025f7adb2f22757a54b706ac8b4fe906"},
+ {file = "pyinstaller-6.10.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e9989f354ae4ed8a3bec7bdb37ae0d170751d6520e500f049c7cd0632d31d5c3"},
+ {file = "pyinstaller-6.10.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b7c90c91921b3749083115b28f30f40abf2bb481ceff196d2b2ce0eaa2b3d429"},
+ {file = "pyinstaller-6.10.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf876d7d93b8b4f28d1ad57fa24645cf43119c79e985dd5e5f7a801245e6f53"},
+ {file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:db05e3f2f10f9f78c56f1fb163d9cb453433429fe4281218ebaf1ebfd39ba942"},
+ {file = "pyinstaller-6.10.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:28eca3817f176fdc19747e1afcf434f13bb9f17a644f611be2c5a61b1f498ed7"},
+ {file = "pyinstaller-6.10.0-py3-none-win32.whl", hash = "sha256:703e041718987e46ba0568a2c71ecf2459fddef57cf9edf3efeed4a53e3dae3f"},
+ {file = "pyinstaller-6.10.0-py3-none-win_amd64.whl", hash = "sha256:95b55966e563e8b8f31a43882aea10169e9a11fdf38e626d86a2907b640c0701"},
+ {file = "pyinstaller-6.10.0-py3-none-win_arm64.whl", hash = "sha256:308e0a8670c9c9ac0cebbf1bbb492e71b6675606f2ec78bc4adfc830d209e087"},
+ {file = "pyinstaller-6.10.0.tar.gz", hash = "sha256:143840f8056ff7b910bf8f16f6cd92cc10a6c2680bb76d0a25d558d543d21270"},
]
[package.dependencies]
@@ -2443,7 +2481,7 @@ importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""}
macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""}
packaging = ">=22.0"
pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""}
-pyinstaller-hooks-contrib = ">=2024.7"
+pyinstaller-hooks-contrib = ">=2024.8"
pywin32-ctypes = {version = ">=0.2.1", markers = "sys_platform == \"win32\""}
setuptools = ">=42.0.0"
@@ -2453,13 +2491,13 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"]
[[package]]
name = "pyinstaller-hooks-contrib"
-version = "2024.7"
+version = "2024.8"
description = "Community maintained hooks for PyInstaller"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pyinstaller_hooks_contrib-2024.7-py2.py3-none-any.whl", hash = "sha256:8bf0775771fbaf96bcd2f4dfd6f7ae6c1dd1b1efe254c7e50477b3c08e7841d8"},
- {file = "pyinstaller_hooks_contrib-2024.7.tar.gz", hash = "sha256:fd5f37dcf99bece184e40642af88be16a9b89613ecb958a8bd1136634fc9fac5"},
+ {file = "pyinstaller_hooks_contrib-2024.8-py3-none-any.whl", hash = "sha256:0057fe9a5c398d3f580e73e58793a1d4a8315ca91c3df01efea1c14ed557825a"},
+ {file = "pyinstaller_hooks_contrib-2024.8.tar.gz", hash = "sha256:29b68d878ab739e967055b56a93eb9b58e529d5b054fbab7a2f2bacf80cef3e2"},
]
[package.dependencies]
@@ -2635,13 +2673,13 @@ files = [
[[package]]
name = "pywin32-ctypes"
-version = "0.2.2"
+version = "0.2.3"
description = "A (partial) reimplementation of pywin32 using ctypes/cffi"
optional = false
python-versions = ">=3.6"
files = [
- {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"},
- {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"},
+ {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"},
+ {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"},
]
[[package]]
@@ -2861,19 +2899,23 @@ files = [
[[package]]
name = "setuptools"
-version = "71.1.0"
+version = "74.1.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
- {file = "setuptools-71.1.0-py3-none-any.whl", hash = "sha256:33874fdc59b3188304b2e7c80d9029097ea31627180896fb549c578ceb8a0855"},
- {file = "setuptools-71.1.0.tar.gz", hash = "sha256:032d42ee9fb536e33087fb66cac5f840eb9391ed05637b3f2a76a7c8fb477936"},
+ {file = "setuptools-74.1.1-py3-none-any.whl", hash = "sha256:fc91b5f89e392ef5b77fe143b17e32f65d3024744fba66dc3afe07201684d766"},
+ {file = "setuptools-74.1.1.tar.gz", hash = "sha256:2353af060c06388be1cecbf5953dcdb1f38362f87a2356c480b6b4d5fcfc8847"},
]
[package.extras]
-core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "ordered-set (>=3.1.1)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
-doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
+core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
+cover = ["pytest-cov"]
+doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
+type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
[[package]]
name = "six"
@@ -3112,43 +3154,41 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
[[package]]
name = "watchdog"
-version = "4.0.1"
+version = "5.0.2"
description = "Filesystem events monitoring"
optional = false
-python-versions = ">=3.8"
-files = [
- {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645"},
- {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b"},
- {file = "watchdog-4.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b"},
- {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5"},
- {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767"},
- {file = "watchdog-4.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459"},
- {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175"},
- {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7"},
- {file = "watchdog-4.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28"},
- {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35"},
- {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db"},
- {file = "watchdog-4.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709"},
- {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba"},
- {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235"},
- {file = "watchdog-4.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682"},
- {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7"},
- {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5"},
- {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193"},
- {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625"},
- {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd"},
- {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_i686.whl", hash = "sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5"},
- {file = "watchdog-4.0.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84"},
- {file = "watchdog-4.0.1-py3-none-win32.whl", hash = "sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429"},
- {file = "watchdog-4.0.1-py3-none-win_amd64.whl", hash = "sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a"},
- {file = "watchdog-4.0.1-py3-none-win_ia64.whl", hash = "sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d"},
- {file = "watchdog-4.0.1.tar.gz", hash = "sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44"},
+python-versions = ">=3.9"
+files = [
+ {file = "watchdog-5.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d961f4123bb3c447d9fcdcb67e1530c366f10ab3a0c7d1c0c9943050936d4877"},
+ {file = "watchdog-5.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72990192cb63872c47d5e5fefe230a401b87fd59d257ee577d61c9e5564c62e5"},
+ {file = "watchdog-5.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6bec703ad90b35a848e05e1b40bf0050da7ca28ead7ac4be724ae5ac2653a1a0"},
+ {file = "watchdog-5.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dae7a1879918f6544201d33666909b040a46421054a50e0f773e0d870ed7438d"},
+ {file = "watchdog-5.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c4a440f725f3b99133de610bfec93d570b13826f89616377715b9cd60424db6e"},
+ {file = "watchdog-5.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8b2918c19e0d48f5f20df458c84692e2a054f02d9df25e6c3c930063eca64c1"},
+ {file = "watchdog-5.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:aa9cd6e24126d4afb3752a3e70fce39f92d0e1a58a236ddf6ee823ff7dba28ee"},
+ {file = "watchdog-5.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f627c5bf5759fdd90195b0c0431f99cff4867d212a67b384442c51136a098ed7"},
+ {file = "watchdog-5.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d7594a6d32cda2b49df3fd9abf9b37c8d2f3eab5df45c24056b4a671ac661619"},
+ {file = "watchdog-5.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba32efcccfe2c58f4d01115440d1672b4eb26cdd6fc5b5818f1fb41f7c3e1889"},
+ {file = "watchdog-5.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:963f7c4c91e3f51c998eeff1b3fb24a52a8a34da4f956e470f4b068bb47b78ee"},
+ {file = "watchdog-5.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8c47150aa12f775e22efff1eee9f0f6beee542a7aa1a985c271b1997d340184f"},
+ {file = "watchdog-5.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:14dd4ed023d79d1f670aa659f449bcd2733c33a35c8ffd88689d9d243885198b"},
+ {file = "watchdog-5.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b84bff0391ad4abe25c2740c7aec0e3de316fdf7764007f41e248422a7760a7f"},
+ {file = "watchdog-5.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e8d5ff39f0a9968952cce548e8e08f849141a4fcc1290b1c17c032ba697b9d7"},
+ {file = "watchdog-5.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fb223456db6e5f7bd9bbd5cd969f05aae82ae21acc00643b60d81c770abd402b"},
+ {file = "watchdog-5.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9814adb768c23727a27792c77812cf4e2fd9853cd280eafa2bcfa62a99e8bd6e"},
+ {file = "watchdog-5.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:901ee48c23f70193d1a7bc2d9ee297df66081dd5f46f0ca011be4f70dec80dab"},
+ {file = "watchdog-5.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:638bcca3d5b1885c6ec47be67bf712b00a9ab3d4b22ec0881f4889ad870bc7e8"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5597c051587f8757798216f2485e85eac583c3b343e9aa09127a3a6f82c65ee8"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:53ed1bf71fcb8475dd0ef4912ab139c294c87b903724b6f4a8bd98e026862e6d"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:29e4a2607bd407d9552c502d38b45a05ec26a8e40cc7e94db9bb48f861fa5abc"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:b6dc8f1d770a8280997e4beae7b9a75a33b268c59e033e72c8a10990097e5fde"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:d2ab34adc9bf1489452965cdb16a924e97d4452fcf88a50b21859068b50b5c3b"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:7d1aa7e4bb0f0c65a1a91ba37c10e19dabf7eaaa282c5787e51371f090748f4b"},
+ {file = "watchdog-5.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:726eef8f8c634ac6584f86c9c53353a010d9f311f6c15a034f3800a7a891d941"},
+ {file = "watchdog-5.0.2-py3-none-win32.whl", hash = "sha256:bda40c57115684d0216556671875e008279dea2dc00fcd3dde126ac8e0d7a2fb"},
+ {file = "watchdog-5.0.2-py3-none-win_amd64.whl", hash = "sha256:d010be060c996db725fbce7e3ef14687cdcc76f4ca0e4339a68cc4532c382a73"},
+ {file = "watchdog-5.0.2-py3-none-win_ia64.whl", hash = "sha256:3960136b2b619510569b90f0cd96408591d6c251a75c97690f4553ca88889769"},
+ {file = "watchdog-5.0.2.tar.gz", hash = "sha256:dcebf7e475001d2cdeb020be630dc5b687e9acdd60d16fea6bb4508e7b94cf76"},
]
[package.extras]
@@ -3203,83 +3243,97 @@ six = "*"
[[package]]
name = "websockets"
-version = "12.0"
+version = "13.0.1"
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
optional = false
python-versions = ">=3.8"
files = [
- {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
- {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
- {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
- {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
- {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
- {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
- {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
- {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
- {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
- {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
- {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
- {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
- {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
- {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
- {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
- {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"},
- {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"},
- {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"},
- {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"},
- {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"},
- {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
- {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
- {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
- {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
- {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
- {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
- {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
- {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
- {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
- {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
- {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
- {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
- {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
+ {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1841c9082a3ba4a05ea824cf6d99570a6a2d8849ef0db16e9c826acb28089e8f"},
+ {file = "websockets-13.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c5870b4a11b77e4caa3937142b650fbbc0914a3e07a0cf3131f35c0587489c1c"},
+ {file = "websockets-13.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f1d3d1f2eb79fe7b0fb02e599b2bf76a7619c79300fc55f0b5e2d382881d4f7f"},
+ {file = "websockets-13.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15c7d62ee071fa94a2fc52c2b472fed4af258d43f9030479d9c4a2de885fd543"},
+ {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6724b554b70d6195ba19650fef5759ef11346f946c07dbbe390e039bcaa7cc3d"},
+ {file = "websockets-13.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a952fa2ae57a42ba7951e6b2605e08a24801a4931b5644dfc68939e041bc7f"},
+ {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17118647c0ea14796364299e942c330d72acc4b248e07e639d34b75067b3cdd8"},
+ {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64a11aae1de4c178fa653b07d90f2fb1a2ed31919a5ea2361a38760192e1858b"},
+ {file = "websockets-13.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0617fd0b1d14309c7eab6ba5deae8a7179959861846cbc5cb528a7531c249448"},
+ {file = "websockets-13.0.1-cp310-cp310-win32.whl", hash = "sha256:11f9976ecbc530248cf162e359a92f37b7b282de88d1d194f2167b5e7ad80ce3"},
+ {file = "websockets-13.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c3c493d0e5141ec055a7d6809a28ac2b88d5b878bb22df8c621ebe79a61123d0"},
+ {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:699ba9dd6a926f82a277063603fc8d586b89f4cb128efc353b749b641fcddda7"},
+ {file = "websockets-13.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf2fae6d85e5dc384bf846f8243ddaa9197f3a1a70044f59399af001fd1f51d4"},
+ {file = "websockets-13.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:52aed6ef21a0f1a2a5e310fb5c42d7555e9c5855476bbd7173c3aa3d8a0302f2"},
+ {file = "websockets-13.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8eb2b9a318542153674c6e377eb8cb9ca0fc011c04475110d3477862f15d29f0"},
+ {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5df891c86fe68b2c38da55b7aea7095beca105933c697d719f3f45f4220a5e0e"},
+ {file = "websockets-13.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac2d146ff30d9dd2fcf917e5d147db037a5c573f0446c564f16f1f94cf87462"},
+ {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b8ac5b46fd798bbbf2ac6620e0437c36a202b08e1f827832c4bf050da081b501"},
+ {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:46af561eba6f9b0848b2c9d2427086cabadf14e0abdd9fde9d72d447df268418"},
+ {file = "websockets-13.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b5a06d7f60bc2fc378a333978470dfc4e1415ee52f5f0fce4f7853eb10c1e9df"},
+ {file = "websockets-13.0.1-cp311-cp311-win32.whl", hash = "sha256:556e70e4f69be1082e6ef26dcb70efcd08d1850f5d6c5f4f2bcb4e397e68f01f"},
+ {file = "websockets-13.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:67494e95d6565bf395476e9d040037ff69c8b3fa356a886b21d8422ad86ae075"},
+ {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f9c9e258e3d5efe199ec23903f5da0eeaad58cf6fccb3547b74fd4750e5ac47a"},
+ {file = "websockets-13.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6b41a1b3b561f1cba8321fb32987552a024a8f67f0d05f06fcf29f0090a1b956"},
+ {file = "websockets-13.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f73e676a46b0fe9426612ce8caeca54c9073191a77c3e9d5c94697aef99296af"},
+ {file = "websockets-13.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f613289f4a94142f914aafad6c6c87903de78eae1e140fa769a7385fb232fdf"},
+ {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f52504023b1480d458adf496dc1c9e9811df4ba4752f0bc1f89ae92f4f07d0c"},
+ {file = "websockets-13.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:139add0f98206cb74109faf3611b7783ceafc928529c62b389917a037d4cfdf4"},
+ {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47236c13be337ef36546004ce8c5580f4b1150d9538b27bf8a5ad8edf23ccfab"},
+ {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c44ca9ade59b2e376612df34e837013e2b273e6c92d7ed6636d0556b6f4db93d"},
+ {file = "websockets-13.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9bbc525f4be3e51b89b2a700f5746c2a6907d2e2ef4513a8daafc98198b92237"},
+ {file = "websockets-13.0.1-cp312-cp312-win32.whl", hash = "sha256:3624fd8664f2577cf8de996db3250662e259bfbc870dd8ebdcf5d7c6ac0b5185"},
+ {file = "websockets-13.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0513c727fb8adffa6d9bf4a4463b2bade0186cbd8c3604ae5540fae18a90cb99"},
+ {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1ee4cc030a4bdab482a37462dbf3ffb7e09334d01dd37d1063be1136a0d825fa"},
+ {file = "websockets-13.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbb0b697cc0655719522406c059eae233abaa3243821cfdfab1215d02ac10231"},
+ {file = "websockets-13.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:acbebec8cb3d4df6e2488fbf34702cbc37fc39ac7abf9449392cefb3305562e9"},
+ {file = "websockets-13.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63848cdb6fcc0bf09d4a155464c46c64ffdb5807ede4fb251da2c2692559ce75"},
+ {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:872afa52a9f4c414d6955c365b6588bc4401272c629ff8321a55f44e3f62b553"},
+ {file = "websockets-13.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e70fec7c54aad4d71eae8e8cab50525e899791fc389ec6f77b95312e4e9920"},
+ {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e82db3756ccb66266504f5a3de05ac6b32f287faacff72462612120074103329"},
+ {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4e85f46ce287f5c52438bb3703d86162263afccf034a5ef13dbe4318e98d86e7"},
+ {file = "websockets-13.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3fea72e4e6edb983908f0db373ae0732b275628901d909c382aae3b592589f2"},
+ {file = "websockets-13.0.1-cp313-cp313-win32.whl", hash = "sha256:254ecf35572fca01a9f789a1d0f543898e222f7b69ecd7d5381d8d8047627bdb"},
+ {file = "websockets-13.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca48914cdd9f2ccd94deab5bcb5ac98025a5ddce98881e5cce762854a5de330b"},
+ {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b74593e9acf18ea5469c3edaa6b27fa7ecf97b30e9dabd5a94c4c940637ab96e"},
+ {file = "websockets-13.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:132511bfd42e77d152c919147078460c88a795af16b50e42a0bd14f0ad71ddd2"},
+ {file = "websockets-13.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:165bedf13556f985a2aa064309baa01462aa79bf6112fbd068ae38993a0e1f1b"},
+ {file = "websockets-13.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e801ca2f448850685417d723ec70298feff3ce4ff687c6f20922c7474b4746ae"},
+ {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30d3a1f041360f029765d8704eae606781e673e8918e6b2c792e0775de51352f"},
+ {file = "websockets-13.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67648f5e50231b5a7f6d83b32f9c525e319f0ddc841be0de64f24928cd75a603"},
+ {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4f0426d51c8f0926a4879390f53c7f5a855e42d68df95fff6032c82c888b5f36"},
+ {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ef48e4137e8799998a343706531e656fdec6797b80efd029117edacb74b0a10a"},
+ {file = "websockets-13.0.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:249aab278810bee585cd0d4de2f08cfd67eed4fc75bde623be163798ed4db2eb"},
+ {file = "websockets-13.0.1-cp38-cp38-win32.whl", hash = "sha256:06c0a667e466fcb56a0886d924b5f29a7f0886199102f0a0e1c60a02a3751cb4"},
+ {file = "websockets-13.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1f3cf6d6ec1142412d4535adabc6bd72a63f5f148c43fe559f06298bc21953c9"},
+ {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1fa082ea38d5de51dd409434edc27c0dcbd5fed2b09b9be982deb6f0508d25bc"},
+ {file = "websockets-13.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4a365bcb7be554e6e1f9f3ed64016e67e2fa03d7b027a33e436aecf194febb63"},
+ {file = "websockets-13.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:10a0dc7242215d794fb1918f69c6bb235f1f627aaf19e77f05336d147fce7c37"},
+ {file = "websockets-13.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59197afd478545b1f73367620407b0083303569c5f2d043afe5363676f2697c9"},
+ {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d20516990d8ad557b5abeb48127b8b779b0b7e6771a265fa3e91767596d7d97"},
+ {file = "websockets-13.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1a2e272d067030048e1fe41aa1ec8cfbbaabce733b3d634304fa2b19e5c897f"},
+ {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad327ac80ba7ee61da85383ca8822ff808ab5ada0e4a030d66703cc025b021c4"},
+ {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:518f90e6dd089d34eaade01101fd8a990921c3ba18ebbe9b0165b46ebff947f0"},
+ {file = "websockets-13.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:68264802399aed6fe9652e89761031acc734fc4c653137a5911c2bfa995d6d6d"},
+ {file = "websockets-13.0.1-cp39-cp39-win32.whl", hash = "sha256:a5dc0c42ded1557cc7c3f0240b24129aefbad88af4f09346164349391dea8e58"},
+ {file = "websockets-13.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b448a0690ef43db5ef31b3a0d9aea79043882b4632cfc3eaab20105edecf6097"},
+ {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:faef9ec6354fe4f9a2c0bbb52fb1ff852effc897e2a4501e25eb3a47cb0a4f89"},
+ {file = "websockets-13.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:03d3f9ba172e0a53e37fa4e636b86cc60c3ab2cfee4935e66ed1d7acaa4625ad"},
+ {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d450f5a7a35662a9b91a64aefa852f0c0308ee256122f5218a42f1d13577d71e"},
+ {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f55b36d17ac50aa8a171b771e15fbe1561217510c8768af3d546f56c7576cdc"},
+ {file = "websockets-13.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14b9c006cac63772b31abbcd3e3abb6228233eec966bf062e89e7fa7ae0b7333"},
+ {file = "websockets-13.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b79915a1179a91f6c5f04ece1e592e2e8a6bd245a0e45d12fd56b2b59e559a32"},
+ {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f40de079779acbcdbb6ed4c65af9f018f8b77c5ec4e17a4b737c05c2db554491"},
+ {file = "websockets-13.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:80e4ba642fc87fa532bac07e5ed7e19d56940b6af6a8c61d4429be48718a380f"},
+ {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a02b0161c43cc9e0232711eff846569fad6ec836a7acab16b3cf97b2344c060"},
+ {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6aa74a45d4cdc028561a7d6ab3272c8b3018e23723100b12e58be9dfa5a24491"},
+ {file = "websockets-13.0.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00fd961943b6c10ee6f0b1130753e50ac5dcd906130dcd77b0003c3ab797d026"},
+ {file = "websockets-13.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d93572720d781331fb10d3da9ca1067817d84ad1e7c31466e9f5e59965618096"},
+ {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:71e6e5a3a3728886caee9ab8752e8113670936a193284be9d6ad2176a137f376"},
+ {file = "websockets-13.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c4a6343e3b0714e80da0b0893543bf9a5b5fa71b846ae640e56e9abc6fbc4c83"},
+ {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a678532018e435396e37422a95e3ab87f75028ac79570ad11f5bf23cd2a7d8c"},
+ {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6716c087e4aa0b9260c4e579bb82e068f84faddb9bfba9906cb87726fa2e870"},
+ {file = "websockets-13.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e33505534f3f673270dd67f81e73550b11de5b538c56fe04435d63c02c3f26b5"},
+ {file = "websockets-13.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acab3539a027a85d568c2573291e864333ec9d912675107d6efceb7e2be5d980"},
+ {file = "websockets-13.0.1-py3-none-any.whl", hash = "sha256:b80f0c51681c517604152eb6a572f5a9378f877763231fddb883ba2f968e8817"},
+ {file = "websockets-13.0.1.tar.gz", hash = "sha256:4d6ece65099411cfd9a48d13701d7438d9c34f479046b34c50ff60bb8834e43e"},
]
[[package]]
@@ -3298,101 +3352,103 @@ watchdog = ["watchdog"]
[[package]]
name = "yarl"
-version = "1.9.4"
+version = "1.9.8"
description = "Yet another URL library"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"},
- {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"},
- {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"},
- {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"},
- {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"},
- {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"},
- {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"},
- {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"},
- {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"},
- {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"},
- {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"},
- {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"},
- {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"},
- {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"},
- {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"},
- {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"},
- {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"},
- {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"},
+ {file = "yarl-1.9.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:08359dbc3540fafa8972db45d3ef2d61370b4c24b8a028a4301bc5d076eee0e2"},
+ {file = "yarl-1.9.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7a716aae4fcecadfe4648268d3c194315152715391f4af6fad50d502be122e9"},
+ {file = "yarl-1.9.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:62223670042a219b8e6fbd2c7f35c456278dcd346d3aba3f2c01c9bdec28f37e"},
+ {file = "yarl-1.9.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18097a9e50ea31c61fece83bac8f63263f0c0c16c439bf82ac729c23f3b170e3"},
+ {file = "yarl-1.9.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5809f8a48c8dab91f708947d358271ef1890c3012d6c45719f49d04af2112057"},
+ {file = "yarl-1.9.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71ff7a22355241f89e850afbc8858fb671ba7e2763af32ebbea158d23a84902a"},
+ {file = "yarl-1.9.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d54e9880e781a490483200a74f6314fb6cf692a8197ccde93adf32bec95626b"},
+ {file = "yarl-1.9.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ad8ea6ab27e27821739dfb94fab63284e3a52055e268f04529dc082fd0d59a2"},
+ {file = "yarl-1.9.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b79e031524259b51cdd1ea41f5053491ad3565b9cecd76389c9f705752d14283"},
+ {file = "yarl-1.9.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:bd91ccded75d080f13ed01a5f5796887916d2e8c0999cd68bcb58f89f9b1c29c"},
+ {file = "yarl-1.9.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:583f48ab25b3906e3716479e8f700c4cc487e44d52766a4ea52b01cb7ea772d6"},
+ {file = "yarl-1.9.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2f3e89838acdaf5bbd69383c408d9e119b4e9efbe8a38fa40045b5c966f918e3"},
+ {file = "yarl-1.9.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a44c0b83d1871e1e1859167a1804143f590f86ac4708380852dca4d8299d8594"},
+ {file = "yarl-1.9.8-cp310-cp310-win32.whl", hash = "sha256:5d39ae58a67b64b470021d18a13529d0c58efc5bf057936ec4b29092d4061030"},
+ {file = "yarl-1.9.8-cp310-cp310-win_amd64.whl", hash = "sha256:f89ade31926b9931bbe29f5c62d4174057e532fb0c72e2e6abdd129fda6a60f3"},
+ {file = "yarl-1.9.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:986296e65b0312c1da168de4ec1bb054b4a7b0ec26e3f9e8dafc06bbb1385030"},
+ {file = "yarl-1.9.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b4c7c015dc813aa5fe15379f3540d178e3743c0f1cf9e4a4a8bff94bd2832a4d"},
+ {file = "yarl-1.9.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:22b2db22f72e1cb8a552ae12dfb748167153c7cbf353c62781915b5328bf2561"},
+ {file = "yarl-1.9.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a567416bfb2a2b093aa64685aa7b6dfb593888784ef91b16fa6b985cceb951"},
+ {file = "yarl-1.9.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:178f4ab054f3a5dc84c8091bd7395b6713aac83af893b62259d5eb3f5359ce7f"},
+ {file = "yarl-1.9.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:02fe9809b29a7dc4a27b769a43c556288d949205db54338871a122b64751e0f4"},
+ {file = "yarl-1.9.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c885a81f6c89b0d45fc0dd88e005c77dd8ba1dac421466d0dbb9192ce6d34e1e"},
+ {file = "yarl-1.9.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99f78f45c8b4c9824e1a37eb0a3ae63ad2dff66434d9620265a4256088be9cda"},
+ {file = "yarl-1.9.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:30929a10be9a13026fd68377aba3223d633370abb93dadd3932754f3dcf4734a"},
+ {file = "yarl-1.9.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ee7c00a1979b3f23c8094dce6d9875453b3cb91b1153d9efaefa6773cf80cdb0"},
+ {file = "yarl-1.9.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e89d76b2aa11287f038a37577528c5f62d9385020b795a011f60dfd1b217cf9f"},
+ {file = "yarl-1.9.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:81fde88456d2cbe005e16aca78ef744f322b3b15184dfe41b5b04f97b46aa5be"},
+ {file = "yarl-1.9.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b3dca0a4e192207f8bb4057725ff95e9a14d53a04728742f2b03692fc91b0a43"},
+ {file = "yarl-1.9.8-cp311-cp311-win32.whl", hash = "sha256:9ea3a8532ea9fc2eeb6fc3def0c341aaeab7625545844f9c0a15350c17f9f479"},
+ {file = "yarl-1.9.8-cp311-cp311-win_amd64.whl", hash = "sha256:c810606719683f4ab92127712efe283674d6ed29a627374411c762852913c2dd"},
+ {file = "yarl-1.9.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b3d373373908e687aa4c8b0666870b0cf65605254ba0819ed8d5af2fc0780496"},
+ {file = "yarl-1.9.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e3d1be58e28825a14fb9561733de62fbe95c892febe7d7a9ebcde916c531d603"},
+ {file = "yarl-1.9.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7318736a8ee9de8217d590866dd716fa3c0895e684e2ec6152d945a4ab758043"},
+ {file = "yarl-1.9.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db3dd602cbf6613dc1e4a6fbde7a1bee86948e5940086090bb505c2ab959bbdf"},
+ {file = "yarl-1.9.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5950226b128a1610f57c1f756fc611fdbdcb1e6b4497ccb05fce76a38915b07"},
+ {file = "yarl-1.9.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b341a995673180ed81a1040228a59e0b47ee687e367b1a03d829fa3c0eb4607e"},
+ {file = "yarl-1.9.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f912153a34698994f32cf683d966014b0dd99c73481302d6159bcb3a8303e84"},
+ {file = "yarl-1.9.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ceab2b16043ae1953863ec240eb918ba1ac40d2aad55225141aac288c606442"},
+ {file = "yarl-1.9.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c0d2bc2646ae2380bb91b9ddc2eb1e1fa6baef128499e817134d1d50c8b6c56"},
+ {file = "yarl-1.9.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ebd98e16ff9948e4d31514c937275017a122b765cb89961dd5d44ecd2cc18140"},
+ {file = "yarl-1.9.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:83273ca458c85d7b026c770a86df6e36349e85100bd2cefe6d0ad7167a8f12a6"},
+ {file = "yarl-1.9.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4511dd73b6aeda0cc39111839923f1545726d621813c9d13355824fba328dbcf"},
+ {file = "yarl-1.9.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ffb9f1cad56c547aa127e2c315e666ee9838156c8a3b14f37ba545b0167aa5e"},
+ {file = "yarl-1.9.8-cp312-cp312-win32.whl", hash = "sha256:5796358c3d6c72b108b570e20ab951463237ec473b6d204da21050feaaaf7dca"},
+ {file = "yarl-1.9.8-cp312-cp312-win_amd64.whl", hash = "sha256:c2dc6e941bf53160b44858d1b24767a056cd83166b69fbdd3b2e401856d8932e"},
+ {file = "yarl-1.9.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cb3d488f049db9522e3a0de50e07bac0c53565acd88a07bc9cf7182fd6890307"},
+ {file = "yarl-1.9.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:50cbf73b6a4b62c3ad633e8920f2791adf485356ef37c9edbd5a1e7de8da2ddc"},
+ {file = "yarl-1.9.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1e0649ee7ac354a3e40ee849707140b14a2cd0cd2dc2062fe620458dfe465c8"},
+ {file = "yarl-1.9.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2501b230e89cad2361719860648f780197812d3be91c7ca6658a097a7e22fc4"},
+ {file = "yarl-1.9.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be441a73f9f49427906274008bd98384d8ca4655981735281c314fc7c145d256"},
+ {file = "yarl-1.9.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7de1968a1c2690b86e32e91acf8ed2043c346293f9bbe1704b9f6a481b73bd11"},
+ {file = "yarl-1.9.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce892a75a2209cf4f7007de21c6f6d607f4b9406ac613a59ad02340f6e933e4"},
+ {file = "yarl-1.9.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:405e75bb94b87cc4167eef0e08d6a539f60633229f7043edc2e65c82ef80e874"},
+ {file = "yarl-1.9.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5811c1906b38f2a203df1266c6dd11680ca85d610d6ee3701dde262a305520"},
+ {file = "yarl-1.9.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:51476f19fe1296d3efe3770179548f5f4822e5c4ead9f5160ba156a6a9f5272c"},
+ {file = "yarl-1.9.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2af144a81883db914636bec646da4dcccfe9db05c2899e7afe90a3d817ffce"},
+ {file = "yarl-1.9.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:8c91b71b0af1fb5454709e34b39e38c975faaa89c0cc8bb744d60300ca710fcd"},
+ {file = "yarl-1.9.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1a562055b5ec6371c307320e8460d16675244e810b20f343371fc52797d23615"},
+ {file = "yarl-1.9.8-cp313-cp313-win32.whl", hash = "sha256:f7442a9342aa04ea60b760a8f0d210e269f881eb0660a2000fa1f8cb89820931"},
+ {file = "yarl-1.9.8-cp313-cp313-win_amd64.whl", hash = "sha256:21ef75d8a18fa47725b50fcb7ae6d23a51c71a7426cdf7097e52f9e12a995eb6"},
+ {file = "yarl-1.9.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd9affa8c18198dfa5a19c63b29ef2a2f35b8efacaf0bdd3e58f974c0ab0108d"},
+ {file = "yarl-1.9.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f79e65f16413a95d9f7633802a2ee34730b3ba1dd0af82811b377057883c4fb7"},
+ {file = "yarl-1.9.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3f8c454cf7e4d3762515ed2b5a40cf2feaeb8a8ed1d121f131a6178e16015319"},
+ {file = "yarl-1.9.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f972fc63a1d6165d1cff650a16a498b0087334f7f9cd7385860c086d009cd49"},
+ {file = "yarl-1.9.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ac4aa2f2d8253b9a5455d5f0ed45687ea9715b78a563490ddf7954337974cb7"},
+ {file = "yarl-1.9.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b001379047de5e03224dc0592f1b0e60738857a9b992d9b636b5050500ecce23"},
+ {file = "yarl-1.9.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39deb5a67b591682e54d1b09b36e79cd608ca27bea1fefed3bcaaa0b05d2b25e"},
+ {file = "yarl-1.9.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffd9dd7eac5d36f53fccdf11e98730b7a628561c77f6c2a9e0909d2a304f34d1"},
+ {file = "yarl-1.9.8-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:497d5fd7dce44b5dcac648c830c99a673d30bc6cd9905b3e255c92c6dc01f537"},
+ {file = "yarl-1.9.8-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:d99011d564f2b5cb4cf1012f9058e08d8d79674332474f7e940131f5952015df"},
+ {file = "yarl-1.9.8-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:600f734296cb99db1af7e34c0dcf8ec9477072f72c4621677637fdc2273af120"},
+ {file = "yarl-1.9.8-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6703deac7bb0dd8b3f0bc3cb6844dab4e74c85c70783ae89bd0b52286ebdc102"},
+ {file = "yarl-1.9.8-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3346e2f641fcf31cf32c5a394d625e0676aba6fadccc06d35435e475753ed05d"},
+ {file = "yarl-1.9.8-cp38-cp38-win32.whl", hash = "sha256:a54f7a63e48156a77a7c0333cefed29ceb004ab683d685a1192b341ac445cb73"},
+ {file = "yarl-1.9.8-cp38-cp38-win_amd64.whl", hash = "sha256:45992ff8d941a1901c35f2ed90a60cb5fee8705ffadff395db4a5fd164473542"},
+ {file = "yarl-1.9.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:590437f092af08e71521cc302940ef897e969152434c825bb3fb8f308b63a8bb"},
+ {file = "yarl-1.9.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:551c26789acd38c7b90a89a1f262291d9f9a6a677185a83b5781e2a2c4258aec"},
+ {file = "yarl-1.9.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:121bf7d647b3f6481ce1030350c1cc4c43e18758010732a449c71a1784ae793d"},
+ {file = "yarl-1.9.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c9db466370e8bc3459912850494ad3401f3664ff3a56842f0d4514166f54c9f"},
+ {file = "yarl-1.9.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff56e21379824f3e3c39a37083d5ab905168b9483b1c0c563dd92eb2db18b251"},
+ {file = "yarl-1.9.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cce910a1510d60c7eff4bb263b28b9afdcc5f6b85c555e492cfe7548a09e2476"},
+ {file = "yarl-1.9.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ba7c4b50cc0bb4caaa54554613ca13db47a24878a4fc1063e6303494fc67567"},
+ {file = "yarl-1.9.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b345de5e725b82e9458dc1381d7e28fe7d7ef93491370461dc98283b9dda51e2"},
+ {file = "yarl-1.9.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:49dd58b79b0fd04e880c90bc570fde68407cc516c58812f0321f5e74c131107c"},
+ {file = "yarl-1.9.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:15fb127bcc19065fd912391a43bc80114635f0062e0465765633ab5d0c7fc3a1"},
+ {file = "yarl-1.9.8-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6f4f87a7c97ba77fdc764b893ae4083c74e5857904962a70025ade0cd42bdbaf"},
+ {file = "yarl-1.9.8-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d336601d9ff3dc3b12263739ab1add25bdd2345d675f59ad49f72d9a6ccbc865"},
+ {file = "yarl-1.9.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3574834e4aaf24e24d12fa4fd53d0b0fd1d70b24a67bed81c44b284377e81d45"},
+ {file = "yarl-1.9.8-cp39-cp39-win32.whl", hash = "sha256:db9305328486539bb7182c15f1ad1ea95dae52245e93a049f2b1d6f04e63674d"},
+ {file = "yarl-1.9.8-cp39-cp39-win_amd64.whl", hash = "sha256:588d62a57c7a43b230557728ec9f252b3f81ad073cb5c0ef48d87cd3f8b6ace2"},
+ {file = "yarl-1.9.8-py3-none-any.whl", hash = "sha256:d1612ce50f23b94897b9ef5eb65b72398a9a83ea990b42825272590f3484dae3"},
+ {file = "yarl-1.9.8.tar.gz", hash = "sha256:3089553548d9ab23152cecb5a71131caaa9e9b16d7fc8196057c374fdc53cc4b"},
]
[package.dependencies]
@@ -3401,18 +3457,22 @@ multidict = ">=4.0"
[[package]]
name = "zipp"
-version = "3.19.2"
+version = "3.20.1"
description = "Backport of pathlib-compatible object wrapper for zip files"
optional = false
python-versions = ">=3.8"
files = [
- {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"},
- {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"},
+ {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"},
+ {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"},
]
[package.extras]
+check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
+cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"]
+enabler = ["pytest-enabler (>=2.2)"]
+test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
+type = ["pytest-mypy"]
[metadata]
lock-version = "2.0"
diff --git a/pyproject.toml b/pyproject.toml
index a02e08312..aa2516ec9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "olas-operate-middleware"
-version = "0.1.0-rc120"
+version = "0.1.0-rc127"
description = ""
authors = ["David Vilela ", "Viraj Patel "]
readme = "README.md"
diff --git a/templates/trader.yaml b/templates/trader.yaml
index ed0b8679d..adabec45b 100644
--- a/templates/trader.yaml
+++ b/templates/trader.yaml
@@ -1,6 +1,6 @@
name: "Trader Agent"
description: "A single-agent service (sovereign agent) placing bets on Omen"
-hash: bafybeicrstlxew36hlxl7pzi73nmd44aibnhwxzkchzlec6t6yhvs7gvhy
+hash: bafybeidu3e3hdx5qt3bclheo7opr4adiil6zs2cger6m733qvhttnlo6na
image: https://operate.olas.network/_next/image?url=%2Fimages%2Fprediction-agent.png&w=3840&q=75
service_version: v0.18.1
home_chain_id: 100