diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index f9b2eb8d..d3970c75 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -10,11 +10,10 @@ on:
jobs:
build-linux:
-
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+ python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
@@ -24,25 +23,27 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
+
- name: Install dependencies
run: |
- python3 -m pip install --upgrade pip pytest cmake scikit-build setuptools
- python3 -m pip install --verbose --editable .
+ python3 -m pip install --upgrade pip cmake scikit-build setuptools
+ python3 -m pip install --verbose --editable .[test,onnx,onnx-tests,convert]
+
- name: Test with pytest
run: |
python3 -m pytest
build-windows:
-
runs-on: windows-latest
strategy:
matrix:
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+ python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
with:
submodules: "true"
+
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
@@ -50,18 +51,18 @@ jobs:
- name: Install dependencies
run: |
- python3 -m pip install --upgrade pip pytest cmake scikit-build setuptools
- python3 -m pip install --verbose --editable .
+ python3 -m pip install --upgrade pip cmake scikit-build setuptools
+ python3 -m pip install --verbose --editable .[test,onnx,onnx-tests,convert]
+
- name: Test with pytest
run: |
python3 -m pytest
build-macos:
-
runs-on: macos-latest
strategy:
matrix:
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+ python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
@@ -71,10 +72,12 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
+
- name: Install dependencies
run: |
- python3 -m pip install --upgrade pip pytest cmake scikit-build setuptools
- python3 -m pip install --verbose --editable .
+ python3 -m pip install --upgrade pip cmake scikit-build setuptools
+ python3 -m pip install --verbose --editable .[test,onnx,onnx-tests,convert]
+
- name: Test with pytest
run: |
python3 -m pytest
@@ -119,7 +122,7 @@ jobs:
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip pytest cmake scikit-build setuptools
- python3 -m pip install --verbose --editable . --config-settings=cmake.args='-DGGML_METAL=On'
+ python3 -m pip install --verbose --editable .[test,onnx,onnx-tests,convert] --config-settings=cmake.args='-DGGML_METAL=On'
- name: Test with pytest
run: |
python3 -m pytest
\ No newline at end of file
diff --git a/README.md b/README.md
index 4f9d5609..0605230d 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,30 @@ If you are having trouble installing `ggml-python` or activating specific featur
pip install ggml-python --verbose --no-cache-dir --force-reinstall --upgrade
```
+# Debugging
+
+## Error: `SIGSEGV` or `Aborted (core dumped)`
+
+Godspeed! You are about to enter the world of debugging native code.
+If you are seeing a `SIGSEGV` or `Aborted (core dumped)` error something has gone horribly wrong.
+A good first step is to try to reproduce the error with a debug build of `ggml-python` and `ggml` and then use a debugger like `gdb` to step through the code and find the issue.
+
+
+```bash
+$ git clone https://github.com/abetlen/ggml-python.git
+$ cd ggml-python
+$ make build.debug # this preserves debug symbols
+$ gdb --args python3 your_script.py
+```
+
+From there you can use `run` to start the script and `bt` to get a backtrace of native code and `py-bt` to get a backtrace of python code.
+
+Additionally, you should use python's built in `breakpoint()` function to set breakpoints in your python code and step through the code.
+
+# API Stability
+
+This project is currently in alpha and the API is subject to change.
+
# License
This project is licensed under the terms of the MIT license.
diff --git a/docs/contrib/onnx.md b/docs/contrib/onnx.md
new file mode 100644
index 00000000..673b2cfe
--- /dev/null
+++ b/docs/contrib/onnx.md
@@ -0,0 +1,152 @@
+# GGML ONNX Runtime
+
+## Getting Started
+
+### Installation
+
+```bash
+pip install ggml-python[onnx]
+```
+
+### Usage
+
+```python
+import onnx
+from ggml.contrib.onnx import GgmlRuntimeBackend
+
+# Load an ONNX model
+model = onnx.load("model.onnx")
+
+# Create a runtime session
+ggml_backend_rep = GgmlRuntimeBackend.prepare(model)
+
+# Run inference
+input = np.random.randn(1, 3, 224, 224).astype(np.float32)
+output = ggml_backend_rep.run([input])
+```
+
+## Technical Overview
+
+The GGML ONNX runtime is a backend for the [ONNX](https://onnx.ai/) model format. It is designed to be used as a drop-in replacement for the ONNX Runtime which leverages ggml for efficient model inference on a wide range of devices.
+
+To use the runtime:
+
+- Models are first converted from PyTorch, TensorFlow, and other frameworks to ONNX
+- ONNX models are then optimized for ggml inference. This includes:
+ - Weight Quantization
+ - Dynamic Subgraph Detection
+ - GPU Offloading
+- The optimized ONNX models are then executed in the GGML ONNX runtime
+
+
+## Operator Support
+
+This table is generated from [`operator_sets.h`](https://github.com/onnx/onnx/blob/main/onnx/defs/operator_sets.h) and may not include all ONNX operators. These are core operators available in all versions starting from ai.onnx version 1.
+
+| ONNX Operator | Status | Implementation Method |
+|:--------------------------------------------------------------------------------------------------|:------------------:|:----------------|
+| [Abs](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Abs) | :white_check_mark: | `ggml_abs` |
+| [Add](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Add) | :white_check_mark: | `ggml_add` |
+| [And](https://github.com/onnx/onnx/blob/main/docs/Operators.md#And) | :white_check_mark: | |
+| [ArgMax](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ArgMax) | :white_check_mark: | |
+| [ArgMin](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ArgMin) | :white_check_mark: | |
+| [AveragePool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#AveragePool) | | |
+| [BatchNormalization](https://github.com/onnx/onnx/blob/main/docs/Operators.md#BatchNormalization) | | |
+| [Cast](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Cast) | :white_check_mark: | |
+| [Ceil](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Ceil) | :white_check_mark: | |
+| [Clip](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Clip) | | |
+| [Concat](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Concat) | :white_check_mark: | `ggml_concat` |
+| [Constant](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Constant) | :white_check_mark: | |
+| [ConstantOfShape](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ConstantOfShape) | :white_check_mark: | |
+| [Conv](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv) | ⚙️ (in progress) | |
+| [ConvTranspose](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ConvTranspose) | ⚙️ (in progress) | |
+| [DepthToSpace](https://github.com/onnx/onnx/blob/main/docs/Operators.md#DepthToSpace) | :white_check_mark: | |
+| [Div](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Div) | :white_check_mark: | `ggml_div` |
+| [Dropout](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Dropout) | ⚙️ (in progress) | |
+| [Elu](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Elu) | :white_check_mark: | `ggml_elu` |
+| [Equal](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Equal) | :white_check_mark: | |
+| [Exp](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Exp) | :white_check_mark: | |
+| [Flatten](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Flatten) | :white_check_mark: | |
+| [Floor](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Floor) | :white_check_mark: | |
+| [GRU](https://github.com/onnx/onnx/blob/main/docs/Operators.md#GRU) | :x: | |
+| [Gather](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Gather) | :white_check_mark: | |
+| [Gemm](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Gemm) | :white_check_mark: | |
+| [GlobalAveragePool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#GlobalAveragePool) | | |
+| [GlobalLpPool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#GlobalLpPool) | | |
+| [GlobalMaxPool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#GlobalMaxPool) | | |
+| [Greater](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Greater) | :white_check_mark: | |
+| [HardSigmoid](https://github.com/onnx/onnx/blob/main/docs/Operators.md#HardSigmoid) | :white_check_mark: | |
+| [Hardmax](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Hardmax) | :white_check_mark: | |
+| [Identity](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Identity) | :white_check_mark: | |
+| [If](https://github.com/onnx/onnx/blob/main/docs/Operators.md#If) | :x: | |
+| [InstanceNormalization](https://github.com/onnx/onnx/blob/main/docs/Operators.md#InstanceNormalization)| :white_check_mark: | |
+| [LRN](https://github.com/onnx/onnx/blob/main/docs/Operators.md#LRN) | :white_check_mark: | |
+| [LSTM](https://github.com/onnx/onnx/blob/main/docs/Operators.md#LSTM) | :x: | |
+| [LeakyRelu](https://github.com/onnx/onnx/blob/main/docs/Operators.md#LeakyRelu) | ⚙️ | |
+| [Less](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Less) | :white_check_mark: | |
+| [Log](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Log) | :white_check_mark: | `ggml_log` |
+| [LogSoftmax](https://github.com/onnx/onnx/blob/main/docs/Operators.md#LogSoftmax) | :white_check_mark: | |
+| [Loop](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Loop) | :x: | |
+| [LpNormalization](https://github.com/onnx/onnx/blob/main/docs/Operators.md#LpNormalization) |:x: (Test case not provided)| |
+| [LpPool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#LpPool) | | |
+| [MatMul](https://github.com/onnx/onnx/blob/main/docs/Operators.md#MatMul) | :white_check_mark: | `ggml_mul_mat` |
+| [Max](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Max) | :white_check_mark: | `ggml_max` |
+| [MaxPool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#MaxPool) | |`ggml.ggml_pool_2d`|
+| [MaxRoiPool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#MaxRoiPool) | | |
+| [Mean](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Mean) | :white_check_mark: |~~`ggml_mean`~~
`ggml_add` + `ggml_div`|
+| [Min](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Min) | :white_check_mark: | |
+| [Mul](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Mul) | :white_check_mark: | `ggml_mul` |
+| [Neg](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Neg) | :white_check_mark: | `ggml_neg` |
+| [Not](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Not) | :white_check_mark: | |
+| [Or](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Or) | :white_check_mark: | |
+| [PRelu](https://github.com/onnx/onnx/blob/main/docs/Operators.md#PRelu) | :white_check_mark: | |
+| [Pad](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Pad) | | |
+| [Pow](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Pow) | :white_check_mark: | |
+| [RNN](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RNN) | :x: | |
+| [RandomNormal](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RandomNormal) |:x: (Test case not provided)| |
+| [RandomNormalLike](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RandomNormalLike) |:x: (Test case not provided)| |
+| [RandomUniform](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RandomUniform) |:x: (Test case not provided)| |
+| [RandomUniformLike](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RandomUniformLike) |:x: (Test case not provided)| |
+| [Reciprocal](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reciprocal) | :white_check_mark: | |
+| [ReduceL1](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceL1) | :white_check_mark: | |
+| [ReduceL2](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceL2) | :white_check_mark: | |
+| [ReduceLogSum](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceLogSum) | :white_check_mark: | |
+| [ReduceLogSumExp](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceLogSumExp) | ⚙️ | |
+| [ReduceMax](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceMax) | :white_check_mark: | |
+| [ReduceMean](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceMean) | :white_check_mark: | |
+| [ReduceMin](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceMin) | :white_check_mark: | |
+| [ReduceProd](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceProd) | :white_check_mark: | |
+| [ReduceSum](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceSum) | :white_check_mark: | |
+| [ReduceSumSquare](https://github.com/onnx/onnx/blob/main/docs/Operators.md#ReduceSumSquare) | :white_check_mark: | |
+| [Relu](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Relu) | :white_check_mark: | `ggml_relu` |
+| [Reshape](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reshape) | :white_check_mark: | `ggml_reshape` |
+| [Selu](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Selu) | :white_check_mark: | |
+| [Shape](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Shape) | :white_check_mark: | |
+| [Sigmoid](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Sigmoid) | :white_check_mark: | |
+| [Size](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Size) | :white_check_mark: | |
+| [Slice](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Slice) | | |
+| [Softmax](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Softmax) | :white_check_mark: | `ggml_soft_max` |
+| [Softplus](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Softplus) | :white_check_mark: | |
+| [Softsign](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Softsign) | :white_check_mark: | |
+| [SpaceToDepth](https://github.com/onnx/onnx/blob/main/docs/Operators.md#SpaceToDepth) | :white_check_mark: | |
+| [Split](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Split) | :white_check_mark: | |
+| [Sqrt](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Sqrt) | :white_check_mark: | `ggml_sqrt` |
+| [Squeeze](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Squeeze) | :white_check_mark: | |
+| [Sub](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Sub) | :white_check_mark: | `ggml_sub` |
+| [Sum](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Sum) | :white_check_mark: | `ggml_sum` |
+| [Tanh](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Tanh) | :white_check_mark: | `ggml_tanh` |
+| [Tile](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Tile) | :white_check_mark: | |
+| [TopK](https://github.com/onnx/onnx/blob/main/docs/Operators.md#TopK) | :white_check_mark: | |
+| [Transpose](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Transpose) | :white_check_mark: | `ggml_transpose` |
+| [Unsqueeze](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Unsqueeze) | :white_check_mark: | |
+| ~~[Upsample](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Upsample)~~ | :x: (Deprecated) | |
+| [Xor](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Xor) | :white_check_mark: | |
+
+## Acknowledgements
+
+The GGML ONNX runtime is built on top of the [ONNX](https://onnx.ai/) and [GGML](ggml.ai)
+
+The core of the runtime was written by Andrei Betlen (@abetlen), David Miller (@dmille), and
+Mohammadreza Anvari (@mrezanvari)
+
+This work would also not be possible without the ggml community, in particular @slaren for their work on the ggml backends and memory allocation api.
diff --git a/examples/instructor/.gitignore b/examples/instructor/.gitignore
new file mode 100644
index 00000000..4a19405e
--- /dev/null
+++ b/examples/instructor/.gitignore
@@ -0,0 +1 @@
+instructor_base_onnx/
\ No newline at end of file
diff --git a/examples/instructor/example.ipynb b/examples/instructor/example.ipynb
new file mode 100644
index 00000000..cad8518d
--- /dev/null
+++ b/examples/instructor/example.ipynb
@@ -0,0 +1,175 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Using OnnxRuntime with instructor-base\n",
+ "- Run `optimum-cli export onnx --model hkunlp/instructor-base instructor_base_onnx/`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Load onnx model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from onnxruntime import InferenceSession\n",
+ "import numpy as np\n",
+ "\n",
+ "\n",
+ "# only need encoder\n",
+ "instructor_encoder_sess = InferenceSession('./instructor_base_onnx/encoder_model.onnx')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Load Instructor model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/mrezanvari/_MyFiles/Programs/Patagona-technologies/ggml-python/examples/instructor/.venv/lib/python3.8/site-packages/InstructorEmbedding/instructor.py:7: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n",
+ " from tqdm.autonotebook import trange\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "load INSTRUCTOR_Transformer\n",
+ "max_seq_length 512\n",
+ "load INSTRUCTOR_Transformer\n",
+ "max_seq_length 512\n"
+ ]
+ }
+ ],
+ "source": [
+ "from InstructorEmbedding import INSTRUCTOR\n",
+ "\n",
+ "# OG model\n",
+ "instructor_model = INSTRUCTOR('hkunlp/instructor-base')\n",
+ "\n",
+ "# onnx test model\n",
+ "instructor_onnx = INSTRUCTOR('hkunlp/instructor-base')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Custom onnx model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import torch.nn as nn\n",
+ "\n",
+ "class OnnxModule(nn.Module):\n",
+ " def __init__(self, inference_session):\n",
+ " super().__init__()\n",
+ " self._inference_session = inference_session\n",
+ " \n",
+ " def forward(self, *args, **kwargs):\n",
+ "\n",
+ " kwargs = {'input_ids': np.array(kwargs['input_ids']), 'attention_mask': np.array(kwargs['attention_mask'])}\n",
+ " return self._inference_session.run(None, kwargs)\n",
+ "\n",
+ "\n",
+ "# replace transfromer model forward call with custom onnx model\n",
+ "\n",
+ "for i in instructor_onnx.modules():\n",
+ " if i._get_name() == 'INSTRUCTOR_Transformer':\n",
+ " i.auto_model.__call__ = OnnxModule(instructor_encoder_sess).forward\n",
+ " \n",
+ " break"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Compare embeddings"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sentence = \"This is a sentence to test instructor embedding model\"\n",
+ "instruction = \"\"\n",
+ "\n",
+ "\n",
+ "real_embeddings = instructor_model.encode([[instruction, sentence]])\n",
+ "onnx_embeddings = instructor_onnx.encode([[instruction, sentence]])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[1.]], dtype=float32)"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.metrics.pairwise import cosine_similarity\n",
+ "\n",
+ "\n",
+ "cosine_similarity(onnx_embeddings, real_embeddings)\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": ".venv",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.2"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/examples/instructor/poetry.lock b/examples/instructor/poetry.lock
new file mode 100644
index 00000000..b0caf768
--- /dev/null
+++ b/examples/instructor/poetry.lock
@@ -0,0 +1,4292 @@
+# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
+
+[[package]]
+name = "aiohttp"
+version = "3.8.5"
+description = "Async http client/server framework (asyncio)"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a94159871304770da4dd371f4291b20cac04e8c94f11bdea1c3478e557fbe0d8"},
+ {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:13bf85afc99ce6f9ee3567b04501f18f9f8dbbb2ea11ed1a2e079670403a7c84"},
+ {file = "aiohttp-3.8.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ce2ac5708501afc4847221a521f7e4b245abf5178cf5ddae9d5b3856ddb2f3a"},
+ {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96943e5dcc37a6529d18766597c491798b7eb7a61d48878611298afc1fca946c"},
+ {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ad5c3c4590bb3cc28b4382f031f3783f25ec223557124c68754a2231d989e2b"},
+ {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c413c633d0512df4dc7fd2373ec06cc6a815b7b6d6c2f208ada7e9e93a5061d"},
+ {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df72ac063b97837a80d80dec8d54c241af059cc9bb42c4de68bd5b61ceb37caa"},
+ {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c48c5c0271149cfe467c0ff8eb941279fd6e3f65c9a388c984e0e6cf57538e14"},
+ {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:368a42363c4d70ab52c2c6420a57f190ed3dfaca6a1b19afda8165ee16416a82"},
+ {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7607ec3ce4993464368505888af5beb446845a014bc676d349efec0e05085905"},
+ {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0d21c684808288a98914e5aaf2a7c6a3179d4df11d249799c32d1808e79503b5"},
+ {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:312fcfbacc7880a8da0ae8b6abc6cc7d752e9caa0051a53d217a650b25e9a691"},
+ {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad093e823df03bb3fd37e7dec9d4670c34f9e24aeace76808fc20a507cace825"},
+ {file = "aiohttp-3.8.5-cp310-cp310-win32.whl", hash = "sha256:33279701c04351a2914e1100b62b2a7fdb9a25995c4a104259f9a5ead7ed4802"},
+ {file = "aiohttp-3.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:6e4a280e4b975a2e7745573e3fc9c9ba0d1194a3738ce1cbaa80626cc9b4f4df"},
+ {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae871a964e1987a943d83d6709d20ec6103ca1eaf52f7e0d36ee1b5bebb8b9b9"},
+ {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:461908b2578955045efde733719d62f2b649c404189a09a632d245b445c9c975"},
+ {file = "aiohttp-3.8.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72a860c215e26192379f57cae5ab12b168b75db8271f111019509a1196dfc780"},
+ {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc14be025665dba6202b6a71cfcdb53210cc498e50068bc088076624471f8bb9"},
+ {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8af740fc2711ad85f1a5c034a435782fbd5b5f8314c9a3ef071424a8158d7f6b"},
+ {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:841cd8233cbd2111a0ef0a522ce016357c5e3aff8a8ce92bcfa14cef890d698f"},
+ {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed1c46fb119f1b59304b5ec89f834f07124cd23ae5b74288e364477641060ff"},
+ {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84f8ae3e09a34f35c18fa57f015cc394bd1389bce02503fb30c394d04ee6b938"},
+ {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62360cb771707cb70a6fd114b9871d20d7dd2163a0feafe43fd115cfe4fe845e"},
+ {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23fb25a9f0a1ca1f24c0a371523546366bb642397c94ab45ad3aedf2941cec6a"},
+ {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0ba0d15164eae3d878260d4c4df859bbdc6466e9e6689c344a13334f988bb53"},
+ {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5d20003b635fc6ae3f96d7260281dfaf1894fc3aa24d1888a9b2628e97c241e5"},
+ {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0175d745d9e85c40dcc51c8f88c74bfbaef9e7afeeeb9d03c37977270303064c"},
+ {file = "aiohttp-3.8.5-cp311-cp311-win32.whl", hash = "sha256:2e1b1e51b0774408f091d268648e3d57f7260c1682e7d3a63cb00d22d71bb945"},
+ {file = "aiohttp-3.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:043d2299f6dfdc92f0ac5e995dfc56668e1587cea7f9aa9d8a78a1b6554e5755"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cae533195e8122584ec87531d6df000ad07737eaa3c81209e85c928854d2195c"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f21e83f355643c345177a5d1d8079f9f28b5133bcd154193b799d380331d5d3"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a75ef35f2df54ad55dbf4b73fe1da96f370e51b10c91f08b19603c64004acc"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e2e9839e14dd5308ee773c97115f1e0a1cb1d75cbeeee9f33824fa5144c7634"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44e65da1de4403d0576473e2344828ef9c4c6244d65cf4b75549bb46d40b8dd"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d847e4cde6ecc19125ccbc9bfac4a7ab37c234dd88fbb3c5c524e8e14da543"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c7a815258e5895d8900aec4454f38dca9aed71085f227537208057853f9d13f2"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:8b929b9bd7cd7c3939f8bcfffa92fae7480bd1aa425279d51a89327d600c704d"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5db3a5b833764280ed7618393832e0853e40f3d3e9aa128ac0ba0f8278d08649"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:a0215ce6041d501f3155dc219712bc41252d0ab76474615b9700d63d4d9292af"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fd1ed388ea7fbed22c4968dd64bab0198de60750a25fe8c0c9d4bef5abe13824"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-win32.whl", hash = "sha256:6e6783bcc45f397fdebc118d772103d751b54cddf5b60fbcc958382d7dd64f3e"},
+ {file = "aiohttp-3.8.5-cp36-cp36m-win_amd64.whl", hash = "sha256:b5411d82cddd212644cf9360879eb5080f0d5f7d809d03262c50dad02f01421a"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:01d4c0c874aa4ddfb8098e85d10b5e875a70adc63db91f1ae65a4b04d3344cda"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5980a746d547a6ba173fd5ee85ce9077e72d118758db05d229044b469d9029a"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a482e6da906d5e6e653be079b29bc173a48e381600161c9932d89dfae5942ef"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80bd372b8d0715c66c974cf57fe363621a02f359f1ec81cba97366948c7fc873"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1161b345c0a444ebcf46bf0a740ba5dcf50612fd3d0528883fdc0eff578006a"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd56db019015b6acfaaf92e1ac40eb8434847d9bf88b4be4efe5bfd260aee692"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:153c2549f6c004d2754cc60603d4668899c9895b8a89397444a9c4efa282aaf4"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4a01951fabc4ce26ab791da5f3f24dca6d9a6f24121746eb19756416ff2d881b"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bfb9162dcf01f615462b995a516ba03e769de0789de1cadc0f916265c257e5d8"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7dde0009408969a43b04c16cbbe252c4f5ef4574ac226bc8815cd7342d2028b6"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4149d34c32f9638f38f544b3977a4c24052042affa895352d3636fa8bffd030a"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-win32.whl", hash = "sha256:68c5a82c8779bdfc6367c967a4a1b2aa52cd3595388bf5961a62158ee8a59e22"},
+ {file = "aiohttp-3.8.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2cf57fb50be5f52bda004b8893e63b48530ed9f0d6c96c84620dc92fe3cd9b9d"},
+ {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eca4bf3734c541dc4f374ad6010a68ff6c6748f00451707f39857f429ca36ced"},
+ {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1274477e4c71ce8cfe6c1ec2f806d57c015ebf84d83373676036e256bc55d690"},
+ {file = "aiohttp-3.8.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c543e54710d6158fc6f439296c7865b29e0b616629767e685a7185fab4a6b9"},
+ {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:910bec0c49637d213f5d9877105d26e0c4a4de2f8b1b29405ff37e9fc0ad52b8"},
+ {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5443910d662db951b2e58eb70b0fbe6b6e2ae613477129a5805d0b66c54b6cb7"},
+ {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e460be6978fc24e3df83193dc0cc4de46c9909ed92dd47d349a452ef49325b7"},
+ {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb1558def481d84f03b45888473fc5a1f35747b5f334ef4e7a571bc0dfcb11f8"},
+ {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34dd0c107799dcbbf7d48b53be761a013c0adf5571bf50c4ecad5643fe9cfcd0"},
+ {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aa1990247f02a54185dc0dff92a6904521172a22664c863a03ff64c42f9b5410"},
+ {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0e584a10f204a617d71d359fe383406305a4b595b333721fa50b867b4a0a1548"},
+ {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a3cf433f127efa43fee6b90ea4c6edf6c4a17109d1d037d1a52abec84d8f2e42"},
+ {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c11f5b099adafb18e65c2c997d57108b5bbeaa9eeee64a84302c0978b1ec948b"},
+ {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:84de26ddf621d7ac4c975dbea4c945860e08cccde492269db4e1538a6a6f3c35"},
+ {file = "aiohttp-3.8.5-cp38-cp38-win32.whl", hash = "sha256:ab88bafedc57dd0aab55fa728ea10c1911f7e4d8b43e1d838a1739f33712921c"},
+ {file = "aiohttp-3.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:5798a9aad1879f626589f3df0f8b79b3608a92e9beab10e5fda02c8a2c60db2e"},
+ {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a6ce61195c6a19c785df04e71a4537e29eaa2c50fe745b732aa937c0c77169f3"},
+ {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:773dd01706d4db536335fcfae6ea2440a70ceb03dd3e7378f3e815b03c97ab51"},
+ {file = "aiohttp-3.8.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f83a552443a526ea38d064588613aca983d0ee0038801bc93c0c916428310c28"},
+ {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f7372f7341fcc16f57b2caded43e81ddd18df53320b6f9f042acad41f8e049a"},
+ {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea353162f249c8097ea63c2169dd1aa55de1e8fecbe63412a9bc50816e87b761"},
+ {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d47ae48db0b2dcf70bc8a3bc72b3de86e2a590fc299fdbbb15af320d2659de"},
+ {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d827176898a2b0b09694fbd1088c7a31836d1a505c243811c87ae53a3f6273c1"},
+ {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3562b06567c06439d8b447037bb655ef69786c590b1de86c7ab81efe1c9c15d8"},
+ {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4e874cbf8caf8959d2adf572a78bba17cb0e9d7e51bb83d86a3697b686a0ab4d"},
+ {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6809a00deaf3810e38c628e9a33271892f815b853605a936e2e9e5129762356c"},
+ {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:33776e945d89b29251b33a7e7d006ce86447b2cfd66db5e5ded4e5cd0340585c"},
+ {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eaeed7abfb5d64c539e2db173f63631455f1196c37d9d8d873fc316470dfbacd"},
+ {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e91d635961bec2d8f19dfeb41a539eb94bd073f075ca6dae6c8dc0ee89ad6f91"},
+ {file = "aiohttp-3.8.5-cp39-cp39-win32.whl", hash = "sha256:00ad4b6f185ec67f3e6562e8a1d2b69660be43070bd0ef6fcec5211154c7df67"},
+ {file = "aiohttp-3.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:c0a9034379a37ae42dea7ac1e048352d96286626251862e448933c0f59cbd79c"},
+ {file = "aiohttp-3.8.5.tar.gz", hash = "sha256:b9552ec52cc147dbf1944ac7ac98af7602e51ea2dcd076ed194ca3c0d1c7d0bc"},
+]
+
+[package.dependencies]
+aiosignal = ">=1.1.2"
+async-timeout = ">=4.0.0a3,<5.0"
+attrs = ">=17.3.0"
+charset-normalizer = ">=2.0,<4.0"
+frozenlist = ">=1.1.1"
+multidict = ">=4.5,<7.0"
+yarl = ">=1.0,<2.0"
+
+[package.extras]
+speedups = ["Brotli", "aiodns", "cchardet"]
+
+[[package]]
+name = "aiosignal"
+version = "1.3.1"
+description = "aiosignal: a list of registered asynchronous callbacks"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"},
+ {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"},
+]
+
+[package.dependencies]
+frozenlist = ">=1.1.0"
+
+[[package]]
+name = "anyio"
+version = "3.7.1"
+description = "High level compatibility layer for multiple asynchronous event loop implementations"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
+ {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
+]
+
+[package.dependencies]
+exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
+idna = ">=2.8"
+sniffio = ">=1.1"
+
+[package.extras]
+doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"]
+test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
+trio = ["trio (<0.22)"]
+
+[[package]]
+name = "appnope"
+version = "0.1.3"
+description = "Disable App Nap on macOS >= 10.9"
+optional = false
+python-versions = "*"
+files = [
+ {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"},
+ {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"},
+]
+
+[[package]]
+name = "argon2-cffi"
+version = "21.3.0"
+description = "The secure Argon2 password hashing algorithm."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "argon2-cffi-21.3.0.tar.gz", hash = "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"},
+ {file = "argon2_cffi-21.3.0-py3-none-any.whl", hash = "sha256:8c976986f2c5c0e5000919e6de187906cfd81fb1c72bf9d88c01177e77da7f80"},
+]
+
+[package.dependencies]
+argon2-cffi-bindings = "*"
+
+[package.extras]
+dev = ["cogapp", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "pre-commit", "pytest", "sphinx", "sphinx-notfound-page", "tomli"]
+docs = ["furo", "sphinx", "sphinx-notfound-page"]
+tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"]
+
+[[package]]
+name = "argon2-cffi-bindings"
+version = "21.2.0"
+description = "Low-level CFFI bindings for Argon2"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"},
+ {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"},
+ {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"},
+ {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"},
+ {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"},
+ {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"},
+ {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"},
+ {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"},
+ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"},
+ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"},
+ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"},
+ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"},
+ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"},
+]
+
+[package.dependencies]
+cffi = ">=1.0.1"
+
+[package.extras]
+dev = ["cogapp", "pre-commit", "pytest", "wheel"]
+tests = ["pytest"]
+
+[[package]]
+name = "arrow"
+version = "1.2.3"
+description = "Better dates & times for Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"},
+ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"},
+]
+
+[package.dependencies]
+python-dateutil = ">=2.7.0"
+
+[[package]]
+name = "asttokens"
+version = "2.2.1"
+description = "Annotate AST trees with source code positions"
+optional = false
+python-versions = "*"
+files = [
+ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"},
+ {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"},
+]
+
+[package.dependencies]
+six = "*"
+
+[package.extras]
+test = ["astroid", "pytest"]
+
+[[package]]
+name = "async-lru"
+version = "2.0.3"
+description = "Simple LRU cache for asyncio"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "async-lru-2.0.3.tar.gz", hash = "sha256:b714c9d1415fca4e264da72a9e2abc66880ce7430e03a973341f88ea4c0d4869"},
+ {file = "async_lru-2.0.3-py3-none-any.whl", hash = "sha256:00c0a8899c20b9c88663a47732689ff98189c9fa08ad9f734d7722f934d250b1"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""}
+
+[[package]]
+name = "async-timeout"
+version = "4.0.2"
+description = "Timeout context manager for asyncio programs"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
+ {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
+]
+
+[[package]]
+name = "attrs"
+version = "23.1.0"
+description = "Classes Without Boilerplate"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"},
+ {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"},
+]
+
+[package.extras]
+cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
+dev = ["attrs[docs,tests]", "pre-commit"]
+docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
+tests = ["attrs[tests-no-zope]", "zope-interface"]
+tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
+
+[[package]]
+name = "babel"
+version = "2.12.1"
+description = "Internationalization utilities"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
+ {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+]
+
+[package.dependencies]
+pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
+
+[[package]]
+name = "backcall"
+version = "0.2.0"
+description = "Specifications for callback functions passed in to an API"
+optional = false
+python-versions = "*"
+files = [
+ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
+ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
+]
+
+[[package]]
+name = "beautifulsoup4"
+version = "4.12.2"
+description = "Screen-scraping library"
+optional = false
+python-versions = ">=3.6.0"
+files = [
+ {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"},
+ {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"},
+]
+
+[package.dependencies]
+soupsieve = ">1.2"
+
+[package.extras]
+html5lib = ["html5lib"]
+lxml = ["lxml"]
+
+[[package]]
+name = "bleach"
+version = "6.0.0"
+description = "An easy safelist-based HTML-sanitizing tool."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"},
+ {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"},
+]
+
+[package.dependencies]
+six = ">=1.9.0"
+webencodings = "*"
+
+[package.extras]
+css = ["tinycss2 (>=1.1.0,<1.2)"]
+
+[[package]]
+name = "certifi"
+version = "2023.7.22"
+description = "Python package for providing Mozilla's CA Bundle."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"},
+ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"},
+]
+
+[[package]]
+name = "cffi"
+version = "1.15.1"
+description = "Foreign Function Interface for Python calling C code."
+optional = false
+python-versions = "*"
+files = [
+ {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
+ {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
+ {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
+ {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
+ {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
+ {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
+ {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
+ {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
+ {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
+ {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
+ {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
+ {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
+ {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
+ {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
+ {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
+ {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
+ {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
+ {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
+ {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
+ {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
+ {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
+ {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
+ {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
+ {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
+ {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
+ {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
+ {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
+ {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
+ {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
+ {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
+ {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
+ {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
+ {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
+ {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
+ {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
+ {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
+ {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
+ {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
+ {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
+ {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
+ {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
+ {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
+ {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
+ {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
+ {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
+ {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
+ {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
+ {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
+ {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
+ {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
+ {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
+ {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
+ {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
+ {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
+ {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
+ {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
+ {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
+ {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
+ {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
+ {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
+ {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
+ {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
+ {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
+ {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
+]
+
+[package.dependencies]
+pycparser = "*"
+
+[[package]]
+name = "charset-normalizer"
+version = "3.2.0"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"},
+ {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"},
+ {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"},
+ {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"},
+ {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"},
+ {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"},
+ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"},
+]
+
+[[package]]
+name = "click"
+version = "8.1.6"
+description = "Composable command line interface toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"},
+ {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "coloredlogs"
+version = "15.0.1"
+description = "Colored terminal output for Python's logging module"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"},
+ {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"},
+]
+
+[package.dependencies]
+humanfriendly = ">=9.1"
+
+[package.extras]
+cron = ["capturer (>=2.4)"]
+
+[[package]]
+name = "comm"
+version = "0.1.3"
+description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "comm-0.1.3-py3-none-any.whl", hash = "sha256:16613c6211e20223f215fc6d3b266a247b6e2641bf4e0a3ad34cb1aff2aa3f37"},
+ {file = "comm-0.1.3.tar.gz", hash = "sha256:a61efa9daffcfbe66fd643ba966f846a624e4e6d6767eda9cf6e993aadaab93e"},
+]
+
+[package.dependencies]
+traitlets = ">=5.3"
+
+[package.extras]
+lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"]
+test = ["pytest"]
+typing = ["mypy (>=0.990)"]
+
+[[package]]
+name = "contourpy"
+version = "1.1.0"
+description = "Python library for calculating contours of 2D quadrilateral grids"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "contourpy-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89f06eff3ce2f4b3eb24c1055a26981bffe4e7264acd86f15b97e40530b794bc"},
+ {file = "contourpy-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dffcc2ddec1782dd2f2ce1ef16f070861af4fb78c69862ce0aab801495dda6a3"},
+ {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25ae46595e22f93592d39a7eac3d638cda552c3e1160255258b695f7b58e5655"},
+ {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17cfaf5ec9862bc93af1ec1f302457371c34e688fbd381f4035a06cd47324f48"},
+ {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18a64814ae7bce73925131381603fff0116e2df25230dfc80d6d690aa6e20b37"},
+ {file = "contourpy-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90c81f22b4f572f8a2110b0b741bb64e5a6427e0a198b2cdc1fbaf85f352a3aa"},
+ {file = "contourpy-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53cc3a40635abedbec7f1bde60f8c189c49e84ac180c665f2cd7c162cc454baa"},
+ {file = "contourpy-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f795597073b09d631782e7245016a4323cf1cf0b4e06eef7ea6627e06a37ff2"},
+ {file = "contourpy-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0b7b04ed0961647691cfe5d82115dd072af7ce8846d31a5fac6c142dcce8b882"},
+ {file = "contourpy-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27bc79200c742f9746d7dd51a734ee326a292d77e7d94c8af6e08d1e6c15d545"},
+ {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052cc634bf903c604ef1a00a5aa093c54f81a2612faedaa43295809ffdde885e"},
+ {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9382a1c0bc46230fb881c36229bfa23d8c303b889b788b939365578d762b5c18"},
+ {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5cec36c5090e75a9ac9dbd0ff4a8cf7cecd60f1b6dc23a374c7d980a1cd710e"},
+ {file = "contourpy-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0cbd657e9bde94cd0e33aa7df94fb73c1ab7799378d3b3f902eb8eb2e04a3a"},
+ {file = "contourpy-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:181cbace49874f4358e2929aaf7ba84006acb76694102e88dd15af861996c16e"},
+ {file = "contourpy-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb3b7d9e6243bfa1efb93ccfe64ec610d85cfe5aec2c25f97fbbd2e58b531256"},
+ {file = "contourpy-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcb41692aa09aeb19c7c213411854402f29f6613845ad2453d30bf421fe68fed"},
+ {file = "contourpy-1.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5d123a5bc63cd34c27ff9c7ac1cd978909e9c71da12e05be0231c608048bb2ae"},
+ {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62013a2cf68abc80dadfd2307299bfa8f5aa0dcaec5b2954caeb5fa094171103"},
+ {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b6616375d7de55797d7a66ee7d087efe27f03d336c27cf1f32c02b8c1a5ac70"},
+ {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317267d915490d1e84577924bd61ba71bf8681a30e0d6c545f577363157e5e94"},
+ {file = "contourpy-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d551f3a442655f3dcc1285723f9acd646ca5858834efeab4598d706206b09c9f"},
+ {file = "contourpy-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e7a117ce7df5a938fe035cad481b0189049e8d92433b4b33aa7fc609344aafa1"},
+ {file = "contourpy-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4f26b25b4f86087e7d75e63212756c38546e70f2a92d2be44f80114826e1cd4"},
+ {file = "contourpy-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc00bb4225d57bff7ebb634646c0ee2a1298402ec10a5fe7af79df9a51c1bfd9"},
+ {file = "contourpy-1.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:189ceb1525eb0655ab8487a9a9c41f42a73ba52d6789754788d1883fb06b2d8a"},
+ {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f2931ed4741f98f74b410b16e5213f71dcccee67518970c42f64153ea9313b9"},
+ {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30f511c05fab7f12e0b1b7730ebdc2ec8deedcfb505bc27eb570ff47c51a8f15"},
+ {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143dde50520a9f90e4a2703f367cf8ec96a73042b72e68fcd184e1279962eb6f"},
+ {file = "contourpy-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e94bef2580e25b5fdb183bf98a2faa2adc5b638736b2c0a4da98691da641316a"},
+ {file = "contourpy-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ed614aea8462735e7d70141374bd7650afd1c3f3cb0c2dbbcbe44e14331bf002"},
+ {file = "contourpy-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:438ba416d02f82b692e371858143970ed2eb6337d9cdbbede0d8ad9f3d7dd17d"},
+ {file = "contourpy-1.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a698c6a7a432789e587168573a864a7ea374c6be8d4f31f9d87c001d5a843493"},
+ {file = "contourpy-1.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397b0ac8a12880412da3551a8cb5a187d3298a72802b45a3bd1805e204ad8439"},
+ {file = "contourpy-1.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a67259c2b493b00e5a4d0f7bfae51fb4b3371395e47d079a4446e9b0f4d70e76"},
+ {file = "contourpy-1.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2b836d22bd2c7bb2700348e4521b25e077255ebb6ab68e351ab5aa91ca27e027"},
+ {file = "contourpy-1.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084eaa568400cfaf7179b847ac871582199b1b44d5699198e9602ecbbb5f6104"},
+ {file = "contourpy-1.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:911ff4fd53e26b019f898f32db0d4956c9d227d51338fb3b03ec72ff0084ee5f"},
+ {file = "contourpy-1.1.0.tar.gz", hash = "sha256:e53046c3863828d21d531cc3b53786e6580eb1ba02477e8681009b6aa0870b21"},
+]
+
+[package.dependencies]
+numpy = ">=1.16"
+
+[package.extras]
+bokeh = ["bokeh", "selenium"]
+docs = ["furo", "sphinx-copybutton"]
+mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.2.0)", "types-Pillow"]
+test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
+test-no-images = ["pytest", "pytest-cov", "wurlitzer"]
+
+[[package]]
+name = "cycler"
+version = "0.11.0"
+description = "Composable style cycles"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
+ {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"},
+]
+
+[[package]]
+name = "datasets"
+version = "2.14.0"
+description = "HuggingFace community-driven open-source library of datasets"
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "datasets-2.14.0-py3-none-any.whl", hash = "sha256:93081cc3d9d0ce860c81f950a3ba23d24704da2eacbe2722092ef4f6ae0ada96"},
+ {file = "datasets-2.14.0.tar.gz", hash = "sha256:1bb3d1c992a593949a8d3e445b358ac1db4ead00e6619ea2e5e7b6dfc222dde1"},
+]
+
+[package.dependencies]
+aiohttp = "*"
+dill = ">=0.3.0,<0.3.8"
+fsspec = {version = ">=2021.11.1", extras = ["http"]}
+huggingface-hub = ">=0.14.0,<1.0.0"
+multiprocess = "*"
+numpy = ">=1.17"
+packaging = "*"
+pandas = "*"
+pyarrow = ">=8.0.0"
+pyyaml = ">=5.1"
+requests = ">=2.19.0"
+tqdm = ">=4.62.1"
+xxhash = "*"
+
+[package.extras]
+apache-beam = ["apache-beam (>=2.26.0,<2.44.0)"]
+audio = ["librosa", "soundfile (>=0.12.1)"]
+benchmarks = ["tensorflow (==2.12.0)", "torch (==2.0.1)", "transformers (==4.30.1)"]
+dev = ["Pillow (>=6.2.1)", "absl-py", "apache-beam (>=2.26.0,<2.44.0)", "black (>=23.1,<24.0)", "elasticsearch (<8.0.0)", "faiss-cpu (>=1.6.4)", "joblib (<1.3.0)", "joblibspark", "librosa", "lz4", "py7zr", "pyspark (>=3.4)", "pytest", "pytest-datadir", "pytest-xdist", "pyyaml (>=5.3.1)", "rarfile (>=4.0)", "ruff (>=0.0.241)", "s3fs", "s3fs (>=2021.11.1)", "soundfile (>=0.12.1)", "sqlalchemy (<2.0.0)", "tensorflow (>=2.3,!=2.6.0,!=2.6.1)", "tensorflow-macos", "tiktoken", "torch", "transformers", "zstandard"]
+docs = ["s3fs"]
+jax = ["jax (>=0.2.8,!=0.3.2,<=0.3.25)", "jaxlib (>=0.1.65,<=0.3.25)"]
+metrics-tests = ["Werkzeug (>=1.0.1)", "accelerate", "bert-score (>=0.3.6)", "jiwer", "langdetect", "mauve-text", "nltk", "requests-file (>=1.5.1)", "rouge-score", "sacrebleu", "sacremoses", "scikit-learn", "scipy", "sentencepiece", "seqeval", "six (>=1.15.0,<1.16.0)", "spacy (>=3.0.0)", "texttable (>=1.6.3)", "tldextract", "tldextract (>=3.1.0)", "toml (>=0.10.1)", "typer (<0.5.0)"]
+quality = ["black (>=23.1,<24.0)", "pyyaml (>=5.3.1)", "ruff (>=0.0.241)"]
+s3 = ["s3fs"]
+tensorflow = ["tensorflow (>=2.2.0,!=2.6.0,!=2.6.1)", "tensorflow-macos"]
+tensorflow-gpu = ["tensorflow-gpu (>=2.2.0,!=2.6.0,!=2.6.1)"]
+tests = ["Pillow (>=6.2.1)", "absl-py", "apache-beam (>=2.26.0,<2.44.0)", "elasticsearch (<8.0.0)", "faiss-cpu (>=1.6.4)", "joblib (<1.3.0)", "joblibspark", "librosa", "lz4", "py7zr", "pyspark (>=3.4)", "pytest", "pytest-datadir", "pytest-xdist", "rarfile (>=4.0)", "s3fs (>=2021.11.1)", "soundfile (>=0.12.1)", "sqlalchemy (<2.0.0)", "tensorflow (>=2.3,!=2.6.0,!=2.6.1)", "tensorflow-macos", "tiktoken", "torch", "transformers", "zstandard"]
+torch = ["torch"]
+vision = ["Pillow (>=6.2.1)"]
+
+[[package]]
+name = "debugpy"
+version = "1.6.7"
+description = "An implementation of the Debug Adapter Protocol for Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "debugpy-1.6.7-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b3e7ac809b991006ad7f857f016fa92014445085711ef111fdc3f74f66144096"},
+ {file = "debugpy-1.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3876611d114a18aafef6383695dfc3f1217c98a9168c1aaf1a02b01ec7d8d1e"},
+ {file = "debugpy-1.6.7-cp310-cp310-win32.whl", hash = "sha256:33edb4afa85c098c24cc361d72ba7c21bb92f501104514d4ffec1fb36e09c01a"},
+ {file = "debugpy-1.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:ed6d5413474e209ba50b1a75b2d9eecf64d41e6e4501977991cdc755dc83ab0f"},
+ {file = "debugpy-1.6.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:38ed626353e7c63f4b11efad659be04c23de2b0d15efff77b60e4740ea685d07"},
+ {file = "debugpy-1.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279d64c408c60431c8ee832dfd9ace7c396984fd7341fa3116aee414e7dcd88d"},
+ {file = "debugpy-1.6.7-cp37-cp37m-win32.whl", hash = "sha256:dbe04e7568aa69361a5b4c47b4493d5680bfa3a911d1e105fbea1b1f23f3eb45"},
+ {file = "debugpy-1.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:f90a2d4ad9a035cee7331c06a4cf2245e38bd7c89554fe3b616d90ab8aab89cc"},
+ {file = "debugpy-1.6.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5224eabbbeddcf1943d4e2821876f3e5d7d383f27390b82da5d9558fd4eb30a9"},
+ {file = "debugpy-1.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae1123dff5bfe548ba1683eb972329ba6d646c3a80e6b4c06cd1b1dd0205e9b"},
+ {file = "debugpy-1.6.7-cp38-cp38-win32.whl", hash = "sha256:9cd10cf338e0907fdcf9eac9087faa30f150ef5445af5a545d307055141dd7a4"},
+ {file = "debugpy-1.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:aaf6da50377ff4056c8ed470da24632b42e4087bc826845daad7af211e00faad"},
+ {file = "debugpy-1.6.7-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0679b7e1e3523bd7d7869447ec67b59728675aadfc038550a63a362b63029d2c"},
+ {file = "debugpy-1.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de86029696e1b3b4d0d49076b9eba606c226e33ae312a57a46dca14ff370894d"},
+ {file = "debugpy-1.6.7-cp39-cp39-win32.whl", hash = "sha256:d71b31117779d9a90b745720c0eab54ae1da76d5b38c8026c654f4a066b0130a"},
+ {file = "debugpy-1.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:c0ff93ae90a03b06d85b2c529eca51ab15457868a377c4cc40a23ab0e4e552a3"},
+ {file = "debugpy-1.6.7-py2.py3-none-any.whl", hash = "sha256:53f7a456bc50706a0eaabecf2d3ce44c4d5010e46dfc65b6b81a518b42866267"},
+ {file = "debugpy-1.6.7.zip", hash = "sha256:c4c2f0810fa25323abfdfa36cbbbb24e5c3b1a42cb762782de64439c575d67f2"},
+]
+
+[[package]]
+name = "decorator"
+version = "5.1.1"
+description = "Decorators for Humans"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
+ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
+]
+
+[[package]]
+name = "defusedxml"
+version = "0.7.1"
+description = "XML bomb protection for Python stdlib modules"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
+ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
+]
+
+[[package]]
+name = "dill"
+version = "0.3.7"
+description = "serialize all of Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"},
+ {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"},
+]
+
+[package.extras]
+graph = ["objgraph (>=1.7.2)"]
+
+[[package]]
+name = "exceptiongroup"
+version = "1.1.2"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"},
+ {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[[package]]
+name = "executing"
+version = "1.2.0"
+description = "Get the currently executing AST node of a frame, and other information"
+optional = false
+python-versions = "*"
+files = [
+ {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"},
+ {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"},
+]
+
+[package.extras]
+tests = ["asttokens", "littleutils", "pytest", "rich"]
+
+[[package]]
+name = "fastjsonschema"
+version = "2.18.0"
+description = "Fastest Python implementation of JSON schema"
+optional = false
+python-versions = "*"
+files = [
+ {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"},
+ {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"},
+]
+
+[package.extras]
+devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"]
+
+[[package]]
+name = "filelock"
+version = "3.12.2"
+description = "A platform independent file lock."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"},
+ {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
+
+[[package]]
+name = "flatbuffers"
+version = "23.5.26"
+description = "The FlatBuffers serialization format for Python"
+optional = false
+python-versions = "*"
+files = [
+ {file = "flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1"},
+ {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"},
+]
+
+[[package]]
+name = "fonttools"
+version = "4.41.1"
+description = "Tools to manipulate font files"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "fonttools-4.41.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a7bbb290d13c6dd718ec2c3db46fe6c5f6811e7ea1e07f145fd8468176398224"},
+ {file = "fonttools-4.41.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ec453a45778524f925a8f20fd26a3326f398bfc55d534e37bab470c5e415caa1"},
+ {file = "fonttools-4.41.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2071267deaa6d93cb16288613419679c77220543551cbe61da02c93d92df72f"},
+ {file = "fonttools-4.41.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e3334d51f0e37e2c6056e67141b2adabc92613a968797e2571ca8a03bd64773"},
+ {file = "fonttools-4.41.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cac73bbef7734e78c60949da11c4903ee5837168e58772371bd42a75872f4f82"},
+ {file = "fonttools-4.41.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:edee0900cf0eedb29d17c7876102d6e5a91ee333882b1f5abc83e85b934cadb5"},
+ {file = "fonttools-4.41.1-cp310-cp310-win32.whl", hash = "sha256:2a22b2c425c698dcd5d6b0ff0b566e8e9663172118db6fd5f1941f9b8063da9b"},
+ {file = "fonttools-4.41.1-cp310-cp310-win_amd64.whl", hash = "sha256:547ab36a799dded58a46fa647266c24d0ed43a66028cd1cd4370b246ad426cac"},
+ {file = "fonttools-4.41.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:849ec722bbf7d3501a0e879e57dec1fc54919d31bff3f690af30bb87970f9784"},
+ {file = "fonttools-4.41.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38cdecd8f1fd4bf4daae7fed1b3170dfc1b523388d6664b2204b351820aa78a7"},
+ {file = "fonttools-4.41.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ae64303ba670f8959fdaaa30ba0c2dabe75364fdec1caeee596c45d51ca3425"},
+ {file = "fonttools-4.41.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f14f3ccea4cc7dd1b277385adf3c3bf18f9860f87eab9c2fb650b0af16800f55"},
+ {file = "fonttools-4.41.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:33191f062549e6bb1a4782c22a04ebd37009c09360e2d6686ac5083774d06d95"},
+ {file = "fonttools-4.41.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:704bccd69b0abb6fab9f5e4d2b75896afa48b427caa2c7988792a2ffce35b441"},
+ {file = "fonttools-4.41.1-cp311-cp311-win32.whl", hash = "sha256:4edc795533421e98f60acee7d28fc8d941ff5ac10f44668c9c3635ad72ae9045"},
+ {file = "fonttools-4.41.1-cp311-cp311-win_amd64.whl", hash = "sha256:aaaef294d8e411f0ecb778a0aefd11bb5884c9b8333cc1011bdaf3b58ca4bd75"},
+ {file = "fonttools-4.41.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3d1f9471134affc1e3b1b806db6e3e2ad3fa99439e332f1881a474c825101096"},
+ {file = "fonttools-4.41.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:59eba8b2e749a1de85760da22333f3d17c42b66e03758855a12a2a542723c6e7"},
+ {file = "fonttools-4.41.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9b3cc10dc9e0834b6665fd63ae0c6964c6bc3d7166e9bc84772e0edd09f9fa2"},
+ {file = "fonttools-4.41.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2c2964bdc827ba6b8a91dc6de792620be4da3922c4cf0599f36a488c07e2b2"},
+ {file = "fonttools-4.41.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7763316111df7b5165529f4183a334aa24c13cdb5375ffa1dc8ce309c8bf4e5c"},
+ {file = "fonttools-4.41.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b2d1ee95be42b80d1f002d1ee0a51d7a435ea90d36f1a5ae331be9962ee5a3f1"},
+ {file = "fonttools-4.41.1-cp38-cp38-win32.whl", hash = "sha256:f48602c0b3fd79cd83a34c40af565fe6db7ac9085c8823b552e6e751e3a5b8be"},
+ {file = "fonttools-4.41.1-cp38-cp38-win_amd64.whl", hash = "sha256:b0938ebbeccf7c80bb9a15e31645cf831572c3a33d5cc69abe436e7000c61b14"},
+ {file = "fonttools-4.41.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e5c2b0a95a221838991e2f0e455dec1ca3a8cc9cd54febd68cc64d40fdb83669"},
+ {file = "fonttools-4.41.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:891cfc5a83b0307688f78b9bb446f03a7a1ad981690ac8362f50518bc6153975"},
+ {file = "fonttools-4.41.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73ef0bb5d60eb02ba4d3a7d23ada32184bd86007cb2de3657cfcb1175325fc83"},
+ {file = "fonttools-4.41.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f240d9adf0583ac8fc1646afe7f4ac039022b6f8fa4f1575a2cfa53675360b69"},
+ {file = "fonttools-4.41.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bdd729744ae7ecd7f7311ad25d99da4999003dcfe43b436cf3c333d4e68de73d"},
+ {file = "fonttools-4.41.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b927e5f466d99c03e6e20961946314b81d6e3490d95865ef88061144d9f62e38"},
+ {file = "fonttools-4.41.1-cp39-cp39-win32.whl", hash = "sha256:afce2aeb80be72b4da7dd114f10f04873ff512793d13ce0b19d12b2a4c44c0f0"},
+ {file = "fonttools-4.41.1-cp39-cp39-win_amd64.whl", hash = "sha256:1df1b6f4c7c4bc8201eb47f3b268adbf2539943aa43c400f84556557e3e109c0"},
+ {file = "fonttools-4.41.1-py3-none-any.whl", hash = "sha256:952cb405f78734cf6466252fec42e206450d1a6715746013f64df9cbd4f896fa"},
+ {file = "fonttools-4.41.1.tar.gz", hash = "sha256:e16a9449f21a93909c5be2f5ed5246420f2316e94195dbfccb5238aaa38f9751"},
+]
+
+[package.extras]
+all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"]
+graphite = ["lz4 (>=1.7.4.2)"]
+interpolatable = ["munkres", "scipy"]
+lxml = ["lxml (>=4.0,<5)"]
+pathops = ["skia-pathops (>=0.5.0)"]
+plot = ["matplotlib"]
+repacker = ["uharfbuzz (>=0.23.0)"]
+symfont = ["sympy"]
+type1 = ["xattr"]
+ufo = ["fs (>=2.2.0,<3)"]
+unicode = ["unicodedata2 (>=15.0.0)"]
+woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
+
+[[package]]
+name = "fqdn"
+version = "1.5.1"
+description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers"
+optional = false
+python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4"
+files = [
+ {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"},
+ {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"},
+]
+
+[[package]]
+name = "frozenlist"
+version = "1.4.0"
+description = "A list-like structure which implements collections.abc.MutableSequence"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"},
+ {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"},
+ {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"},
+ {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"},
+ {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"},
+ {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"},
+ {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"},
+ {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"},
+ {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"},
+ {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"},
+ {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"},
+ {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"},
+ {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"},
+ {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"},
+ {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"},
+ {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"},
+ {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"},
+ {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"},
+ {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"},
+ {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"},
+ {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"},
+ {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"},
+ {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"},
+ {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"},
+ {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"},
+ {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"},
+ {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"},
+ {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"},
+ {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"},
+ {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"},
+ {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"},
+ {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"},
+ {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"},
+ {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"},
+ {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"},
+ {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"},
+ {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"},
+ {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"},
+ {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"},
+ {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"},
+ {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"},
+ {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"},
+ {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"},
+ {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"},
+ {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"},
+ {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"},
+ {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"},
+ {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"},
+ {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"},
+ {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"},
+ {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"},
+ {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"},
+ {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"},
+ {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"},
+ {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"},
+ {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"},
+ {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"},
+ {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"},
+ {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"},
+ {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"},
+ {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"},
+]
+
+[[package]]
+name = "fsspec"
+version = "2023.6.0"
+description = "File-system specification"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "fsspec-2023.6.0-py3-none-any.whl", hash = "sha256:1cbad1faef3e391fba6dc005ae9b5bdcbf43005c9167ce78c915549c352c869a"},
+ {file = "fsspec-2023.6.0.tar.gz", hash = "sha256:d0b2f935446169753e7a5c5c55681c54ea91996cc67be93c39a154fb3a2742af"},
+]
+
+[package.dependencies]
+aiohttp = {version = "<4.0.0a0 || >4.0.0a0,<4.0.0a1 || >4.0.0a1", optional = true, markers = "extra == \"http\""}
+requests = {version = "*", optional = true, markers = "extra == \"http\""}
+
+[package.extras]
+abfs = ["adlfs"]
+adl = ["adlfs"]
+arrow = ["pyarrow (>=1)"]
+dask = ["dask", "distributed"]
+devel = ["pytest", "pytest-cov"]
+dropbox = ["dropbox", "dropboxdrivefs", "requests"]
+full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"]
+fuse = ["fusepy"]
+gcs = ["gcsfs"]
+git = ["pygit2"]
+github = ["requests"]
+gs = ["gcsfs"]
+gui = ["panel"]
+hdfs = ["pyarrow (>=1)"]
+http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"]
+libarchive = ["libarchive-c"]
+oci = ["ocifs"]
+s3 = ["s3fs"]
+sftp = ["paramiko"]
+smb = ["smbprotocol"]
+ssh = ["paramiko"]
+tqdm = ["tqdm"]
+
+[[package]]
+name = "graphviz"
+version = "0.20.1"
+description = "Simple Python interface for Graphviz"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"},
+ {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"},
+]
+
+[package.extras]
+dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"]
+docs = ["sphinx (>=5)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"]
+test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>=3)"]
+
+[[package]]
+name = "huggingface-hub"
+version = "0.16.4"
+description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "huggingface_hub-0.16.4-py3-none-any.whl", hash = "sha256:0d3df29932f334fead024afc7cb4cc5149d955238b8b5e42dcf9740d6995a349"},
+ {file = "huggingface_hub-0.16.4.tar.gz", hash = "sha256:608c7d4f3d368b326d1747f91523dbd1f692871e8e2e7a4750314a2dd8b63e14"},
+]
+
+[package.dependencies]
+filelock = "*"
+fsspec = "*"
+packaging = ">=20.9"
+pyyaml = ">=5.1"
+requests = "*"
+tqdm = ">=4.42.1"
+typing-extensions = ">=3.7.4.3"
+
+[package.extras]
+all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "black (>=23.1,<24.0)", "gradio", "jedi", "mypy (==0.982)", "numpy", "pydantic", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-vcr", "pytest-xdist", "ruff (>=0.0.241)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "urllib3 (<2.0)"]
+cli = ["InquirerPy (==0.3.4)"]
+dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "black (>=23.1,<24.0)", "gradio", "jedi", "mypy (==0.982)", "numpy", "pydantic", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-vcr", "pytest-xdist", "ruff (>=0.0.241)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "urllib3 (<2.0)"]
+fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
+inference = ["aiohttp", "pydantic"]
+quality = ["black (>=23.1,<24.0)", "mypy (==0.982)", "ruff (>=0.0.241)"]
+tensorflow = ["graphviz", "pydot", "tensorflow"]
+testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
+torch = ["torch"]
+typing = ["pydantic", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3"]
+
+[[package]]
+name = "humanfriendly"
+version = "10.0"
+description = "Human friendly output for text interfaces using Python"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"},
+ {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"},
+]
+
+[package.dependencies]
+pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""}
+
+[[package]]
+name = "humanize"
+version = "4.7.0"
+description = "Python humanize utilities"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "humanize-4.7.0-py3-none-any.whl", hash = "sha256:df7c429c2d27372b249d3f26eb53b07b166b661326e0325793e0a988082e3889"},
+ {file = "humanize-4.7.0.tar.gz", hash = "sha256:7ca0e43e870981fa684acb5b062deb307218193bca1a01f2b2676479df849b3a"},
+]
+
+[package.extras]
+tests = ["freezegun", "pytest", "pytest-cov"]
+
+[[package]]
+name = "idna"
+version = "3.4"
+description = "Internationalized Domain Names in Applications (IDNA)"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
+
+[[package]]
+name = "importlib-metadata"
+version = "6.8.0"
+description = "Read metadata from Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
+ {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
+]
+
+[package.dependencies]
+zipp = ">=0.5"
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+perf = ["ipython"]
+testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
+
+[[package]]
+name = "importlib-resources"
+version = "6.0.0"
+description = "Read resources from Python packages"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "importlib_resources-6.0.0-py3-none-any.whl", hash = "sha256:d952faee11004c045f785bb5636e8f885bed30dc3c940d5d42798a2a4541c185"},
+ {file = "importlib_resources-6.0.0.tar.gz", hash = "sha256:4cf94875a8368bd89531a756df9a9ebe1f150e0f885030b461237bc7f2d905f2"},
+]
+
+[package.dependencies]
+zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
+
+[[package]]
+name = "instructorembedding"
+version = "1.0.1"
+description = "Text embedding tool"
+optional = false
+python-versions = "*"
+files = [
+ {file = "InstructorEmbedding-1.0.1-py2.py3-none-any.whl", hash = "sha256:c8d0c11d0bab3ede023104e1f3de6a3471bf71208cc272d1ef72bae771e7d1a3"},
+ {file = "InstructorEmbedding-1.0.1.tar.gz", hash = "sha256:886495ddd561bad57e8e7d5e8ee44c4243b1d80b538a25d32d37350f6082ee62"},
+]
+
+[[package]]
+name = "ipykernel"
+version = "6.25.0"
+description = "IPython Kernel for Jupyter"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "ipykernel-6.25.0-py3-none-any.whl", hash = "sha256:f0042e867ac3f6bca1679e6a88cbd6a58ed93a44f9d0866aecde6efe8de76659"},
+ {file = "ipykernel-6.25.0.tar.gz", hash = "sha256:e342ce84712861be4b248c4a73472be4702c1b0dd77448bfd6bcfb3af9d5ddf9"},
+]
+
+[package.dependencies]
+appnope = {version = "*", markers = "platform_system == \"Darwin\""}
+comm = ">=0.1.1"
+debugpy = ">=1.6.5"
+ipython = ">=7.23.1"
+jupyter-client = ">=6.1.12"
+jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
+matplotlib-inline = ">=0.1"
+nest-asyncio = "*"
+packaging = "*"
+psutil = "*"
+pyzmq = ">=20"
+tornado = ">=6.1"
+traitlets = ">=5.4.0"
+
+[package.extras]
+cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"]
+docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"]
+pyqt5 = ["pyqt5"]
+pyside6 = ["pyside6"]
+test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov", "pytest-timeout"]
+
+[[package]]
+name = "ipython"
+version = "8.12.2"
+description = "IPython: Productive Interactive Computing"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "ipython-8.12.2-py3-none-any.whl", hash = "sha256:ea8801f15dfe4ffb76dea1b09b847430ffd70d827b41735c64a0638a04103bfc"},
+ {file = "ipython-8.12.2.tar.gz", hash = "sha256:c7b80eb7f5a855a88efc971fda506ff7a91c280b42cdae26643e0f601ea281ea"},
+]
+
+[package.dependencies]
+appnope = {version = "*", markers = "sys_platform == \"darwin\""}
+backcall = "*"
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+decorator = "*"
+jedi = ">=0.16"
+matplotlib-inline = "*"
+pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
+pickleshare = "*"
+prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0"
+pygments = ">=2.4.0"
+stack-data = "*"
+traitlets = ">=5"
+typing-extensions = {version = "*", markers = "python_version < \"3.10\""}
+
+[package.extras]
+all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"]
+black = ["black"]
+doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"]
+kernel = ["ipykernel"]
+nbconvert = ["nbconvert"]
+nbformat = ["nbformat"]
+notebook = ["ipywidgets", "notebook"]
+parallel = ["ipyparallel"]
+qtconsole = ["qtconsole"]
+test = ["pytest (<7.1)", "pytest-asyncio", "testpath"]
+test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"]
+
+[[package]]
+name = "ipython-genutils"
+version = "0.2.0"
+description = "Vestigial utilities from IPython"
+optional = false
+python-versions = "*"
+files = [
+ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},
+ {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"},
+]
+
+[[package]]
+name = "ipywidgets"
+version = "8.0.7"
+description = "Jupyter interactive widgets"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "ipywidgets-8.0.7-py3-none-any.whl", hash = "sha256:e0aed0c95a1e55b6a123f64305245578bdc09e52965a34941c2b6a578b8c64a0"},
+ {file = "ipywidgets-8.0.7.tar.gz", hash = "sha256:50ace0a8886e9a0d68b980db82f94c25d55d21ff2340ed36f802dd9365e94acf"},
+]
+
+[package.dependencies]
+ipykernel = ">=4.5.1"
+ipython = ">=6.1.0"
+jupyterlab-widgets = ">=3.0.7,<3.1.0"
+traitlets = ">=4.3.1"
+widgetsnbextension = ">=4.0.7,<4.1.0"
+
+[package.extras]
+test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"]
+
+[[package]]
+name = "isoduration"
+version = "20.11.0"
+description = "Operations with ISO 8601 durations"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"},
+ {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"},
+]
+
+[package.dependencies]
+arrow = ">=0.15.0"
+
+[[package]]
+name = "jedi"
+version = "0.18.2"
+description = "An autocompletion tool for Python that can be used for text editors."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"},
+ {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"},
+]
+
+[package.dependencies]
+parso = ">=0.8.0,<0.9.0"
+
+[package.extras]
+docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"]
+qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
+testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"]
+
+[[package]]
+name = "jinja2"
+version = "3.1.2"
+description = "A very fast and expressive template engine."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
+ {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
+[[package]]
+name = "joblib"
+version = "1.3.1"
+description = "Lightweight pipelining with Python functions"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "joblib-1.3.1-py3-none-any.whl", hash = "sha256:89cf0529520e01b3de7ac7b74a8102c90d16d54c64b5dd98cafcd14307fdf915"},
+ {file = "joblib-1.3.1.tar.gz", hash = "sha256:1f937906df65329ba98013dc9692fe22a4c5e4a648112de500508b18a21b41e3"},
+]
+
+[[package]]
+name = "json5"
+version = "0.9.14"
+description = "A Python implementation of the JSON5 data format."
+optional = false
+python-versions = "*"
+files = [
+ {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"},
+ {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"},
+]
+
+[package.extras]
+dev = ["hypothesis"]
+
+[[package]]
+name = "jsonpointer"
+version = "2.4"
+description = "Identify specific nodes in a JSON document (RFC 6901)"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*"
+files = [
+ {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"},
+ {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"},
+]
+
+[[package]]
+name = "jsonschema"
+version = "4.18.4"
+description = "An implementation of JSON Schema validation for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jsonschema-4.18.4-py3-none-any.whl", hash = "sha256:971be834317c22daaa9132340a51c01b50910724082c2c1a2ac87eeec153a3fe"},
+ {file = "jsonschema-4.18.4.tar.gz", hash = "sha256:fb3642735399fa958c0d2aad7057901554596c63349f4f6b283c493cf692a25d"},
+]
+
+[package.dependencies]
+attrs = ">=22.2.0"
+fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""}
+idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""}
+importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""}
+isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""}
+jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""}
+jsonschema-specifications = ">=2023.03.6"
+pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""}
+referencing = ">=0.28.4"
+rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""}
+rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""}
+rpds-py = ">=0.7.1"
+uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""}
+webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""}
+
+[package.extras]
+format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
+format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"]
+
+[[package]]
+name = "jsonschema-specifications"
+version = "2023.7.1"
+description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"},
+ {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"},
+]
+
+[package.dependencies]
+importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""}
+referencing = ">=0.28.0"
+
+[[package]]
+name = "jupyter"
+version = "1.0.0"
+description = "Jupyter metapackage. Install all the Jupyter components in one go."
+optional = false
+python-versions = "*"
+files = [
+ {file = "jupyter-1.0.0-py2.py3-none-any.whl", hash = "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"},
+ {file = "jupyter-1.0.0.tar.gz", hash = "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"},
+ {file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"},
+]
+
+[package.dependencies]
+ipykernel = "*"
+ipywidgets = "*"
+jupyter-console = "*"
+nbconvert = "*"
+notebook = "*"
+qtconsole = "*"
+
+[[package]]
+name = "jupyter-client"
+version = "8.3.0"
+description = "Jupyter protocol implementation and client libraries"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"},
+ {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""}
+jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
+python-dateutil = ">=2.8.2"
+pyzmq = ">=23.0"
+tornado = ">=6.2"
+traitlets = ">=5.3"
+
+[package.extras]
+docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
+test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"]
+
+[[package]]
+name = "jupyter-console"
+version = "6.6.3"
+description = "Jupyter terminal console"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485"},
+ {file = "jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539"},
+]
+
+[package.dependencies]
+ipykernel = ">=6.14"
+ipython = "*"
+jupyter-client = ">=7.0.0"
+jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
+prompt-toolkit = ">=3.0.30"
+pygments = "*"
+pyzmq = ">=17"
+traitlets = ">=5.4"
+
+[package.extras]
+test = ["flaky", "pexpect", "pytest"]
+
+[[package]]
+name = "jupyter-core"
+version = "5.3.1"
+description = "Jupyter core package. A base package on which Jupyter projects rely."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jupyter_core-5.3.1-py3-none-any.whl", hash = "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce"},
+ {file = "jupyter_core-5.3.1.tar.gz", hash = "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba"},
+]
+
+[package.dependencies]
+platformdirs = ">=2.5"
+pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""}
+traitlets = ">=5.3"
+
+[package.extras]
+docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"]
+test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"]
+
+[[package]]
+name = "jupyter-events"
+version = "0.6.3"
+description = "Jupyter Event System library"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"},
+ {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"},
+]
+
+[package.dependencies]
+jsonschema = {version = ">=3.2.0", extras = ["format-nongpl"]}
+python-json-logger = ">=2.0.4"
+pyyaml = ">=5.3"
+rfc3339-validator = "*"
+rfc3986-validator = ">=0.1.1"
+traitlets = ">=5.3"
+
+[package.extras]
+cli = ["click", "rich"]
+docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"]
+test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "pytest-cov", "rich"]
+
+[[package]]
+name = "jupyter-lsp"
+version = "2.2.0"
+description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jupyter-lsp-2.2.0.tar.gz", hash = "sha256:8ebbcb533adb41e5d635eb8fe82956b0aafbf0fd443b6c4bfa906edeeb8635a1"},
+ {file = "jupyter_lsp-2.2.0-py3-none-any.whl", hash = "sha256:9e06b8b4f7dd50300b70dd1a78c0c3b0c3d8fa68e0f2d8a5d1fbab62072aca3f"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""}
+jupyter-server = ">=1.1.2"
+
+[[package]]
+name = "jupyter-server"
+version = "2.7.0"
+description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jupyter_server-2.7.0-py3-none-any.whl", hash = "sha256:6a77912aff643e53fa14bdb2634884b52b784a4be77ce8e93f7283faed0f0849"},
+ {file = "jupyter_server-2.7.0.tar.gz", hash = "sha256:36da0a266d31a41ac335a366c88933c17dfa5bb817a48f5c02c16d303bc9477f"},
+]
+
+[package.dependencies]
+anyio = ">=3.1.0"
+argon2-cffi = "*"
+jinja2 = "*"
+jupyter-client = ">=7.4.4"
+jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
+jupyter-events = ">=0.6.0"
+jupyter-server-terminals = "*"
+nbconvert = ">=6.4.4"
+nbformat = ">=5.3.0"
+overrides = "*"
+packaging = "*"
+prometheus-client = "*"
+pywinpty = {version = "*", markers = "os_name == \"nt\""}
+pyzmq = ">=24"
+send2trash = "*"
+terminado = ">=0.8.3"
+tornado = ">=6.2.0"
+traitlets = ">=5.6.0"
+websocket-client = "*"
+
+[package.extras]
+docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"]
+test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"]
+
+[[package]]
+name = "jupyter-server-terminals"
+version = "0.4.4"
+description = "A Jupyter Server Extension Providing Terminals."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"},
+ {file = "jupyter_server_terminals-0.4.4.tar.gz", hash = "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d"},
+]
+
+[package.dependencies]
+pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""}
+terminado = ">=0.8.3"
+
+[package.extras]
+docs = ["jinja2", "jupyter-server", "mistune (<3.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"]
+test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"]
+
+[[package]]
+name = "jupyterlab"
+version = "4.0.3"
+description = "JupyterLab computational environment"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "jupyterlab-4.0.3-py3-none-any.whl", hash = "sha256:d369944391b1d15f2d1f3cb965fb67352956279b2ae6f03ce7947a43940a8301"},
+ {file = "jupyterlab-4.0.3.tar.gz", hash = "sha256:e14d1ce46a613028111d0d476a1d7d6b094003b7462bac669f5b478317abcb39"},
+]
+
+[package.dependencies]
+async-lru = ">=1.0.0"
+importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""}
+importlib-resources = {version = ">=1.4", markers = "python_version < \"3.9\""}
+ipykernel = "*"
+jinja2 = ">=3.0.3"
+jupyter-core = "*"
+jupyter-lsp = ">=2.0.0"
+jupyter-server = ">=2.4.0,<3"
+jupyterlab-server = ">=2.19.0,<3"
+notebook-shim = ">=0.2"
+packaging = "*"
+tomli = {version = "*", markers = "python_version < \"3.11\""}
+tornado = ">=6.2.0"
+traitlets = "*"
+
+[package.extras]
+dev = ["black[jupyter] (==23.3.0)", "build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.0.271)"]
+docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8)", "sphinx-copybutton"]
+docs-screenshots = ["altair (==5.0.1)", "ipython (==8.14.0)", "ipywidgets (==8.0.6)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post0)", "matplotlib (==3.7.1)", "nbconvert (>=7.0.0)", "pandas (==2.0.2)", "scipy (==1.10.1)", "vega-datasets (==0.9.0)"]
+test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"]
+
+[[package]]
+name = "jupyterlab-pygments"
+version = "0.2.2"
+description = "Pygments theme using JupyterLab CSS variables"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"},
+ {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"},
+]
+
+[[package]]
+name = "jupyterlab-server"
+version = "2.24.0"
+description = "A set of server components for JupyterLab and JupyterLab like applications."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "jupyterlab_server-2.24.0-py3-none-any.whl", hash = "sha256:5f077e142bb8dc9b843d960f940c513581bceca3793a0d80f9c67d9522c4e876"},
+ {file = "jupyterlab_server-2.24.0.tar.gz", hash = "sha256:4e6f99e0a5579bbbc32e449c4dbb039561d4f1a7827d5733273ed56738f21f07"},
+]
+
+[package.dependencies]
+babel = ">=2.10"
+importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""}
+jinja2 = ">=3.0.3"
+json5 = ">=0.9.0"
+jsonschema = ">=4.17.3"
+jupyter-server = ">=1.21,<3"
+packaging = ">=21.3"
+requests = ">=2.28"
+
+[package.extras]
+docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"]
+openapi = ["openapi-core (>=0.16.1,<0.17.0)", "ruamel-yaml"]
+test = ["hatch", "ipykernel", "jupyterlab-server[openapi]", "openapi-spec-validator (>=0.5.1,<0.7.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"]
+
+[[package]]
+name = "jupyterlab-widgets"
+version = "3.0.8"
+description = "Jupyter interactive widgets for JupyterLab"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "jupyterlab_widgets-3.0.8-py3-none-any.whl", hash = "sha256:4715912d6ceab839c9db35953c764b3214ebbc9161c809f6e0510168845dfdf5"},
+ {file = "jupyterlab_widgets-3.0.8.tar.gz", hash = "sha256:d428ab97b8d87cc7c54cbf37644d6e0f0e662f23876e05fa460a73ec3257252a"},
+]
+
+[[package]]
+name = "jyquickhelper"
+version = "0.4.220"
+description = "Helpers for Jupyter notebooks: automated menu, JSON visualizer, plug javascript"
+optional = false
+python-versions = "*"
+files = [
+ {file = "jyquickhelper-0.4.220-py3-none-any.whl", hash = "sha256:d26c039e6432907292daa07a6b7a16796ab7833a97f96877f9de55f82cf1a4b3"},
+]
+
+[package.dependencies]
+ipython = "*"
+jupyter = "*"
+notebook = "*"
+
+[[package]]
+name = "kiwisolver"
+version = "1.4.4"
+description = "A fast implementation of the Cassowary constraint solver"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"},
+ {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"},
+]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.3"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
+ {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
+ {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"},
+ {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
+ {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
+ {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
+ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
+]
+
+[[package]]
+name = "matplotlib"
+version = "3.7.2"
+description = "Python plotting package"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:2699f7e73a76d4c110f4f25be9d2496d6ab4f17345307738557d345f099e07de"},
+ {file = "matplotlib-3.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a8035ba590658bae7562786c9cc6ea1a84aa49d3afab157e414c9e2ea74f496d"},
+ {file = "matplotlib-3.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f8e4a49493add46ad4a8c92f63e19d548b2b6ebbed75c6b4c7f46f57d36cdd1"},
+ {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71667eb2ccca4c3537d9414b1bc00554cb7f91527c17ee4ec38027201f8f1603"},
+ {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:152ee0b569a37630d8628534c628456b28686e085d51394da6b71ef84c4da201"},
+ {file = "matplotlib-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070f8dddd1f5939e60aacb8fa08f19551f4b0140fab16a3669d5cd6e9cb28fc8"},
+ {file = "matplotlib-3.7.2-cp310-cp310-win32.whl", hash = "sha256:fdbb46fad4fb47443b5b8ac76904b2e7a66556844f33370861b4788db0f8816a"},
+ {file = "matplotlib-3.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:23fb1750934e5f0128f9423db27c474aa32534cec21f7b2153262b066a581fd1"},
+ {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:30e1409b857aa8a747c5d4f85f63a79e479835f8dffc52992ac1f3f25837b544"},
+ {file = "matplotlib-3.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:50e0a55ec74bf2d7a0ebf50ac580a209582c2dd0f7ab51bc270f1b4a0027454e"},
+ {file = "matplotlib-3.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac60daa1dc83e8821eed155796b0f7888b6b916cf61d620a4ddd8200ac70cd64"},
+ {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305e3da477dc8607336ba10bac96986d6308d614706cae2efe7d3ffa60465b24"},
+ {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c308b255efb9b06b23874236ec0f10f026673ad6515f602027cc8ac7805352d"},
+ {file = "matplotlib-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60c521e21031632aa0d87ca5ba0c1c05f3daacadb34c093585a0be6780f698e4"},
+ {file = "matplotlib-3.7.2-cp311-cp311-win32.whl", hash = "sha256:26bede320d77e469fdf1bde212de0ec889169b04f7f1179b8930d66f82b30cbc"},
+ {file = "matplotlib-3.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4860132c8c05261a5f5f8467f1b269bf1c7c23902d75f2be57c4a7f2394b3e"},
+ {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a1733b8e84e7e40a9853e505fe68cc54339f97273bdfe6f3ed980095f769ddc7"},
+ {file = "matplotlib-3.7.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d9881356dc48e58910c53af82b57183879129fa30492be69058c5b0d9fddf391"},
+ {file = "matplotlib-3.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f081c03f413f59390a80b3e351cc2b2ea0205839714dbc364519bcf51f4b56ca"},
+ {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1cd120fca3407a225168238b790bd5c528f0fafde6172b140a2f3ab7a4ea63e9"},
+ {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2c1590b90aa7bd741b54c62b78de05d4186271e34e2377e0289d943b3522273"},
+ {file = "matplotlib-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d2ff3c984b8a569bc1383cd468fc06b70d7b59d5c2854ca39f1436ae8394117"},
+ {file = "matplotlib-3.7.2-cp38-cp38-win32.whl", hash = "sha256:5dea00b62d28654b71ca92463656d80646675628d0828e08a5f3b57e12869e13"},
+ {file = "matplotlib-3.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:0f506a1776ee94f9e131af1ac6efa6e5bc7cb606a3e389b0ccb6e657f60bb676"},
+ {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:6515e878f91894c2e4340d81f0911857998ccaf04dbc1bba781e3d89cbf70608"},
+ {file = "matplotlib-3.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:71f7a8c6b124e904db550f5b9fe483d28b896d4135e45c4ea381ad3b8a0e3256"},
+ {file = "matplotlib-3.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12f01b92ecd518e0697da4d97d163b2b3aa55eb3eb4e2c98235b3396d7dad55f"},
+ {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7e28d6396563955f7af437894a36bf2b279462239a41028323e04b85179058b"},
+ {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbcf59334ff645e6a67cd5f78b4b2cdb76384cdf587fa0d2dc85f634a72e1a3e"},
+ {file = "matplotlib-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:318c89edde72ff95d8df67d82aca03861240512994a597a435a1011ba18dbc7f"},
+ {file = "matplotlib-3.7.2-cp39-cp39-win32.whl", hash = "sha256:ce55289d5659b5b12b3db4dc9b7075b70cef5631e56530f14b2945e8836f2d20"},
+ {file = "matplotlib-3.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:2ecb5be2b2815431c81dc115667e33da0f5a1bcf6143980d180d09a717c4a12e"},
+ {file = "matplotlib-3.7.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdcd28360dbb6203fb5219b1a5658df226ac9bebc2542a9e8f457de959d713d0"},
+ {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3cca3e842b11b55b52c6fb8bd6a4088693829acbfcdb3e815fa9b7d5c92c1b"},
+ {file = "matplotlib-3.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebf577c7a6744e9e1bd3fee45fc74a02710b214f94e2bde344912d85e0c9af7c"},
+ {file = "matplotlib-3.7.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:936bba394682049919dda062d33435b3be211dc3dcaa011e09634f060ec878b2"},
+ {file = "matplotlib-3.7.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bc221ffbc2150458b1cd71cdd9ddd5bb37962b036e41b8be258280b5b01da1dd"},
+ {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35d74ebdb3f71f112b36c2629cf32323adfbf42679e2751252acd468f5001c07"},
+ {file = "matplotlib-3.7.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717157e61b3a71d3d26ad4e1770dc85156c9af435659a25ee6407dc866cb258d"},
+ {file = "matplotlib-3.7.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:20f844d6be031948148ba49605c8b96dfe7d3711d1b63592830d650622458c11"},
+ {file = "matplotlib-3.7.2.tar.gz", hash = "sha256:a8cdb91dddb04436bd2f098b8fdf4b81352e68cf4d2c6756fcc414791076569b"},
+]
+
+[package.dependencies]
+contourpy = ">=1.0.1"
+cycler = ">=0.10"
+fonttools = ">=4.22.0"
+importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""}
+kiwisolver = ">=1.0.1"
+numpy = ">=1.20"
+packaging = ">=20.0"
+pillow = ">=6.2.0"
+pyparsing = ">=2.3.1,<3.1"
+python-dateutil = ">=2.7"
+
+[[package]]
+name = "matplotlib-inline"
+version = "0.1.6"
+description = "Inline Matplotlib backend for Jupyter"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"},
+ {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
+]
+
+[package.dependencies]
+traitlets = "*"
+
+[[package]]
+name = "mistune"
+version = "3.0.1"
+description = "A sane and fast Markdown parser with useful plugins and renderers"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "mistune-3.0.1-py3-none-any.whl", hash = "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6"},
+ {file = "mistune-3.0.1.tar.gz", hash = "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c"},
+]
+
+[[package]]
+name = "mpmath"
+version = "1.3.0"
+description = "Python library for arbitrary-precision floating-point arithmetic"
+optional = false
+python-versions = "*"
+files = [
+ {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"},
+ {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"},
+]
+
+[package.extras]
+develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"]
+docs = ["sphinx"]
+gmpy = ["gmpy2 (>=2.1.0a4)"]
+tests = ["pytest (>=4.6)"]
+
+[[package]]
+name = "multidict"
+version = "6.0.4"
+description = "multidict implementation"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"},
+ {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"},
+ {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"},
+ {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"},
+ {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"},
+ {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"},
+ {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"},
+ {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"},
+ {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"},
+ {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"},
+ {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"},
+ {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"},
+ {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"},
+ {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"},
+ {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"},
+ {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"},
+ {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"},
+ {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"},
+ {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"},
+ {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"},
+ {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"},
+ {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"},
+ {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"},
+ {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"},
+ {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"},
+ {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"},
+ {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"},
+ {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"},
+ {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"},
+ {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"},
+ {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"},
+ {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"},
+ {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"},
+ {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"},
+ {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"},
+ {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"},
+ {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"},
+ {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"},
+ {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"},
+ {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"},
+ {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"},
+ {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"},
+ {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"},
+ {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"},
+ {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"},
+ {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"},
+ {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"},
+ {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"},
+ {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"},
+ {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"},
+ {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"},
+ {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"},
+ {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"},
+ {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"},
+ {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"},
+ {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"},
+ {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"},
+ {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"},
+ {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"},
+ {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"},
+ {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"},
+ {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"},
+ {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"},
+ {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"},
+ {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"},
+ {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"},
+ {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"},
+ {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"},
+ {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"},
+ {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"},
+ {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"},
+ {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"},
+ {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"},
+ {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
+]
+
+[[package]]
+name = "multiprocess"
+version = "0.70.15"
+description = "better multiprocessing and multithreading in Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "multiprocess-0.70.15-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:aa36c7ed16f508091438687fe9baa393a7a8e206731d321e443745e743a0d4e5"},
+ {file = "multiprocess-0.70.15-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:20e024018c46d0d1602024c613007ac948f9754659e3853b0aa705e83f6931d8"},
+ {file = "multiprocess-0.70.15-pp37-pypy37_pp73-manylinux_2_24_i686.whl", hash = "sha256:e576062981c91f0fe8a463c3d52506e598dfc51320a8dd8d78b987dfca91c5db"},
+ {file = "multiprocess-0.70.15-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:e73f497e6696a0f5433ada2b3d599ae733b87a6e8b008e387c62ac9127add177"},
+ {file = "multiprocess-0.70.15-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:73db2e7b32dcc7f9b0f075c2ffa45c90b6729d3f1805f27e88534c8d321a1be5"},
+ {file = "multiprocess-0.70.15-pp38-pypy38_pp73-manylinux_2_24_i686.whl", hash = "sha256:4271647bd8a49c28ecd6eb56a7fdbd3c212c45529ad5303b40b3c65fc6928e5f"},
+ {file = "multiprocess-0.70.15-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:cf981fb998d6ec3208cb14f0cf2e9e80216e834f5d51fd09ebc937c32b960902"},
+ {file = "multiprocess-0.70.15-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:18f9f2c7063346d1617bd1684fdcae8d33380ae96b99427260f562e1a1228b67"},
+ {file = "multiprocess-0.70.15-pp39-pypy39_pp73-manylinux_2_24_i686.whl", hash = "sha256:0eac53214d664c49a34695e5824872db4006b1a465edd7459a251809c3773370"},
+ {file = "multiprocess-0.70.15-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:1a51dd34096db47fb21fa2b839e615b051d51b97af9a67afbcdaa67186b44883"},
+ {file = "multiprocess-0.70.15-py310-none-any.whl", hash = "sha256:7dd58e33235e83cf09d625e55cffd7b0f0eede7ee9223cdd666a87624f60c21a"},
+ {file = "multiprocess-0.70.15-py311-none-any.whl", hash = "sha256:134f89053d82c9ed3b73edd3a2531eb791e602d4f4156fc92a79259590bd9670"},
+ {file = "multiprocess-0.70.15-py37-none-any.whl", hash = "sha256:f7d4a1629bccb433114c3b4885f69eccc200994323c80f6feee73b0edc9199c5"},
+ {file = "multiprocess-0.70.15-py38-none-any.whl", hash = "sha256:bee9afba476c91f9ebee7beeee0601face9eff67d822e893f9a893725fbd6316"},
+ {file = "multiprocess-0.70.15-py39-none-any.whl", hash = "sha256:3e0953f5d52b4c76f1c973eaf8214554d146f2be5decb48e928e55c7a2d19338"},
+ {file = "multiprocess-0.70.15.tar.gz", hash = "sha256:f20eed3036c0ef477b07a4177cf7c1ba520d9a2677870a4f47fe026f0cd6787e"},
+]
+
+[package.dependencies]
+dill = ">=0.3.7"
+
+[[package]]
+name = "nbclient"
+version = "0.8.0"
+description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor."
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"},
+ {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"},
+]
+
+[package.dependencies]
+jupyter-client = ">=6.1.12"
+jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
+nbformat = ">=5.1"
+traitlets = ">=5.4"
+
+[package.extras]
+dev = ["pre-commit"]
+docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"]
+test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"]
+
+[[package]]
+name = "nbconvert"
+version = "7.7.3"
+description = "Converting Jupyter Notebooks"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "nbconvert-7.7.3-py3-none-any.whl", hash = "sha256:3022adadff3f86578a47fab7c2228bb3ca9c56a24345642a22f917f6168b48fc"},
+ {file = "nbconvert-7.7.3.tar.gz", hash = "sha256:4a5996bf5f3cd16aa0431897ba1aa4c64842c2079f434b3dc6b8c4b252ef3355"},
+]
+
+[package.dependencies]
+beautifulsoup4 = "*"
+bleach = "!=5.0.0"
+defusedxml = "*"
+importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""}
+jinja2 = ">=3.0"
+jupyter-core = ">=4.7"
+jupyterlab-pygments = "*"
+markupsafe = ">=2.0"
+mistune = ">=2.0.3,<4"
+nbclient = ">=0.5.0"
+nbformat = ">=5.7"
+packaging = "*"
+pandocfilters = ">=1.4.1"
+pygments = ">=2.4.1"
+tinycss2 = "*"
+traitlets = ">=5.1"
+
+[package.extras]
+all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"]
+docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"]
+qtpdf = ["nbconvert[qtpng]"]
+qtpng = ["pyqtwebengine (>=5.15)"]
+serve = ["tornado (>=6.1)"]
+test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"]
+webpdf = ["playwright"]
+
+[[package]]
+name = "nbformat"
+version = "5.9.1"
+description = "The Jupyter Notebook format"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "nbformat-5.9.1-py3-none-any.whl", hash = "sha256:b7968ebf4811178a4108ee837eae1442e3f054132100f0359219e9ed1ce3ca45"},
+ {file = "nbformat-5.9.1.tar.gz", hash = "sha256:3a7f52d040639cbd8a3890218c8b0ffb93211588c57446c90095e32ba5881b5d"},
+]
+
+[package.dependencies]
+fastjsonschema = "*"
+jsonschema = ">=2.6"
+jupyter-core = "*"
+traitlets = ">=5.1"
+
+[package.extras]
+docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
+test = ["pep440", "pre-commit", "pytest", "testpath"]
+
+[[package]]
+name = "nest-asyncio"
+version = "1.5.6"
+description = "Patch asyncio to allow nested event loops"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"},
+ {file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"},
+]
+
+[[package]]
+name = "networkx"
+version = "3.1"
+description = "Python package for creating and manipulating graphs and networks"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"},
+ {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"},
+]
+
+[package.extras]
+default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"]
+developer = ["mypy (>=1.1)", "pre-commit (>=3.2)"]
+doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.13)", "sphinx (>=6.1)", "sphinx-gallery (>=0.12)", "texext (>=0.6.7)"]
+extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"]
+test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"]
+
+[[package]]
+name = "nltk"
+version = "3.8.1"
+description = "Natural Language Toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"},
+ {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"},
+]
+
+[package.dependencies]
+click = "*"
+joblib = "*"
+regex = ">=2021.8.3"
+tqdm = "*"
+
+[package.extras]
+all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"]
+corenlp = ["requests"]
+machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"]
+plot = ["matplotlib"]
+tgrep = ["pyparsing"]
+twitter = ["twython"]
+
+[[package]]
+name = "notebook"
+version = "7.0.0"
+description = "Jupyter Notebook - A web-based notebook environment for interactive computing"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "notebook-7.0.0-py3-none-any.whl", hash = "sha256:71b4e695e658763a2766613176491854708fb46fbe7664bf5e494deeeab92d60"},
+ {file = "notebook-7.0.0.tar.gz", hash = "sha256:38b55e6939df0ba73b53212c3b234e41102f1789e0158606cedaebf00abef6c8"},
+]
+
+[package.dependencies]
+importlib-resources = {version = ">=5.0", markers = "python_version < \"3.9\""}
+jupyter-server = ">=2.4.0,<3"
+jupyterlab = ">=4.0.2,<5"
+jupyterlab-server = ">=2.22.1,<3"
+notebook-shim = ">=0.2,<0.3"
+tornado = ">=6.2.0"
+
+[package.extras]
+dev = ["hatch", "pre-commit"]
+docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
+test = ["ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.22.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"]
+
+[[package]]
+name = "notebook-shim"
+version = "0.2.3"
+description = "A shim layer for notebook traits and config"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "notebook_shim-0.2.3-py3-none-any.whl", hash = "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7"},
+ {file = "notebook_shim-0.2.3.tar.gz", hash = "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9"},
+]
+
+[package.dependencies]
+jupyter-server = ">=1.8,<3"
+
+[package.extras]
+test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"]
+
+[[package]]
+name = "numpy"
+version = "1.24.4"
+description = "Fundamental package for array computing in Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"},
+ {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"},
+ {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"},
+ {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"},
+ {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"},
+ {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"},
+ {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"},
+ {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"},
+ {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"},
+ {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"},
+ {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"},
+ {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"},
+ {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"},
+ {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"},
+ {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"},
+ {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"},
+ {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"},
+ {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"},
+ {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"},
+ {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"},
+ {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"},
+ {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"},
+ {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"},
+ {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"},
+ {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"},
+ {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"},
+ {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"},
+ {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"},
+]
+
+[[package]]
+name = "onnx"
+version = "1.14.0"
+description = "Open Neural Network Exchange"
+optional = false
+python-versions = "*"
+files = [
+ {file = "onnx-1.14.0-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:fb35c2c347486416f87f41557242c05d7ee804d3676c6c8c98eef6f5b1889e7b"},
+ {file = "onnx-1.14.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd683d4aa6d55365582055a6c1e10a55d6c08a59e9216cbb67e37ad3a5b2b980"},
+ {file = "onnx-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00b0d2620c10dcb9ec33441e807dc5851d2843d445e0faab5e22c8ad6874a67a"},
+ {file = "onnx-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01893a4a2d70b68e8ee20269ccde4069a6fd243dc9e296643e2afeb0050527bc"},
+ {file = "onnx-1.14.0-cp310-cp310-win32.whl", hash = "sha256:0753b0f118be71ff109dd994a3d6769e5871e9feaddfada77931c63f9de534b3"},
+ {file = "onnx-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:d8c3a2354d9d997c7a4a5e467b5373c98dc549d4a33c77d5723e1eda7e87559c"},
+ {file = "onnx-1.14.0-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:5e780fd1ed25493596a141e93303d0b2897acb9ebfdee7047a916d8f8e525ab3"},
+ {file = "onnx-1.14.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9d28d64cbac3ebdc0c9761a300340c60ec60316099906e354e5059e90335fb3b"},
+ {file = "onnx-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba92fed1aa27cba385bc3890fbbe6484603e837e67c957b22899f93c70990cc4"},
+ {file = "onnx-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fab7e6e1c2d9d6479edad8e9088cdfd87ea293cb08f31565adabfb33c6e5789"},
+ {file = "onnx-1.14.0-cp311-cp311-win32.whl", hash = "sha256:6e966f5ef38a0521595cad6a1d14d9ae205c593d2824d8c1fa044fa5ba15370d"},
+ {file = "onnx-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:1fe8ba794d261d722018bd1385f02f966aace0fcb5448881ab5dd55ab0ebb81b"},
+ {file = "onnx-1.14.0-cp37-cp37m-macosx_10_12_universal2.whl", hash = "sha256:c16dacf577700ff9cb076c61c880d1a4bc612eed96280396a54ee1e1bd7e2d68"},
+ {file = "onnx-1.14.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:bbdca51da9fa9ec43eebd8c640bf71c05daa2afbeaa2c6478466470e28e41111"},
+ {file = "onnx-1.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3315c304d23a06ebd07fffe2456ab7f1e0a8dba317393d5c17a671ae2da6645e"},
+ {file = "onnx-1.14.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1545159f2e7fbc5b4a3ae032cd4d9ddeafc62c4f27fe22cbc3ecff49338992"},
+ {file = "onnx-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:18cd98f7e234e268cb60c47a1f8ea5f6ffba50fe11de924b17498b1571d0cd2c"},
+ {file = "onnx-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a8f7454acded506b6359ee0837c8527c64964973d7d25ed6b16b7d4314599502"},
+ {file = "onnx-1.14.0-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:a9702e7dd120bca421a820020151cbb1003077e17ded29cc8d44ff32a9a57ad8"},
+ {file = "onnx-1.14.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:369c3ecace7e8c7df6efbcbc712b262626796ae4a83decd29111afafa025a30c"},
+ {file = "onnx-1.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fbcdc1a0c1057785bc5f7254aca0cf0b49d19c74696f1ade107638054157315"},
+ {file = "onnx-1.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed099fbdada4accead109a4479d5f73fb974566cce8d3c6fca94774f9645934c"},
+ {file = "onnx-1.14.0-cp38-cp38-win32.whl", hash = "sha256:296e689aa54a9ae4e560b2bb149a64e96775699a0624af5f631665b9cda90482"},
+ {file = "onnx-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:e1607f97007515df303c1f40b77363545af99a1f32d2f73240c8aa526cdbd109"},
+ {file = "onnx-1.14.0-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:7800b6ec74b1fe3fbb3bf4a2380e2f4007c1a7f2d6927599ad40eead6eae5e19"},
+ {file = "onnx-1.14.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:45d3effe59e20d0a9fdc51f5bb8f38299086c79576b894ed945e6a058c4b210a"},
+ {file = "onnx-1.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a593b46015326feb949781d030cb1d0d5d388cca52bff2e2995badf55d56b38d"},
+ {file = "onnx-1.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54614942574415ef3f0bce0800c6f41ecea8201f8042754e204ee8c0a8e473e1"},
+ {file = "onnx-1.14.0-cp39-cp39-win32.whl", hash = "sha256:dcfaeb2d15e93c456003fac13ffa35144ba9d2666a83e2cef650dd5c90a2b768"},
+ {file = "onnx-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:0639427ac61e5a0181f4f7c89f9fc82b3c9715c95071f9c3de79bbe303a4ae65"},
+ {file = "onnx-1.14.0.tar.gz", hash = "sha256:43b85087c6b919de66872a043c7f4899fe6f840e11ffca7e662b2ce9e4cc2927"},
+]
+
+[package.dependencies]
+numpy = "*"
+protobuf = ">=3.20.2"
+typing-extensions = ">=3.6.2.1"
+
+[package.extras]
+lint = ["lintrunner (>=0.10.0)", "lintrunner-adapters (>=0.3)"]
+
+[[package]]
+name = "onnxruntime"
+version = "1.15.1"
+description = "ONNX Runtime is a runtime accelerator for Machine Learning models"
+optional = false
+python-versions = "*"
+files = [
+ {file = "onnxruntime-1.15.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:baad59e6a763237fa39545325d29c16f98b8a45d2dfc524c67631e2e3ba44d16"},
+ {file = "onnxruntime-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:568c2db848f619a0a93e843c028e9fb4879929d40b04bd60f9ba6eb8d2e93421"},
+ {file = "onnxruntime-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69088d7784bb04dedfd9e883e2c96e4adf8ae0451acdd0abb78d68f59ecc6d9d"},
+ {file = "onnxruntime-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cef43737b2cd886d5d718d100f56ec78c9c476c5db5f8f946e95024978fe754"},
+ {file = "onnxruntime-1.15.1-cp310-cp310-win32.whl", hash = "sha256:79d7e65abb44a47c633ede8e53fe7b9756c272efaf169758c482c983cca98d7e"},
+ {file = "onnxruntime-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:8bc4c47682933a7a2c79808688aad5f12581305e182be552de50783b5438e6bd"},
+ {file = "onnxruntime-1.15.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:652b2cb777f76446e3cc41072dd3d1585a6388aeff92b9de656724bc22e241e4"},
+ {file = "onnxruntime-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89b86dbed15740abc385055a29c9673a212600248d702737ce856515bdeddc88"},
+ {file = "onnxruntime-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed5cdd9ee748149a57f4cdfa67187a0d68f75240645a3c688299dcd08742cc98"},
+ {file = "onnxruntime-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f748cce6a70ed38c19658615c55f4eedb9192765a4e9c4bd2682adfe980698d"},
+ {file = "onnxruntime-1.15.1-cp311-cp311-win32.whl", hash = "sha256:e0312046e814c40066e7823da58075992d51364cbe739eeeb2345ec440c3ac59"},
+ {file = "onnxruntime-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:f0980969689cb956c22bd1318b271e1be260060b37f3ddd82c7d63bd7f2d9a79"},
+ {file = "onnxruntime-1.15.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:345986cfdbd6f4b20a89b6a6cd9abd3e2ced2926ae0b6e91fefa8149f95c0f09"},
+ {file = "onnxruntime-1.15.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d7b3ad75e040f1e95757f69826a11051737b31584938a26d466a0234c6de98"},
+ {file = "onnxruntime-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3603d07b829bcc1c14963a76103e257aade8861eb208173b300cc26e118ec2f8"},
+ {file = "onnxruntime-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3df0625b9295daf1f7409ea55f72e1eeb38d54f5769add53372e79ddc3cf98d"},
+ {file = "onnxruntime-1.15.1-cp38-cp38-win32.whl", hash = "sha256:f68b47fdf1a0406c0292f81ac993e2a2ae3e8b166b436d590eb221f64e8e187a"},
+ {file = "onnxruntime-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:52d762d297cc3f731f54fa65a3e329b813164970671547bef6414d0ed52765c9"},
+ {file = "onnxruntime-1.15.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:99228f9f03dc1fc8af89a28c9f942e8bd3e97e894e263abe1a32e4ddb1f6363b"},
+ {file = "onnxruntime-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:45db7f96febb0cf23e3af147f35c4f8de1a37dd252d1cef853c242c2780250cd"},
+ {file = "onnxruntime-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bafc112a36db25c821b90ab747644041cb4218f6575889775a2c12dd958b8c3"},
+ {file = "onnxruntime-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:985693d18f2d46aa34fd44d7f65ff620660b2c8fa4b8ec365c2ca353f0fbdb27"},
+ {file = "onnxruntime-1.15.1-cp39-cp39-win32.whl", hash = "sha256:708eb31b0c04724bf0f01c1309a9e69bbc09b85beb750e5662c8aed29f1ff9fd"},
+ {file = "onnxruntime-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:73d6de4c42dfde1e9dbea04773e6dc23346c8cda9c7e08c6554fafc97ac60138"},
+]
+
+[package.dependencies]
+coloredlogs = "*"
+flatbuffers = "*"
+numpy = ">=1.21.6"
+packaging = "*"
+protobuf = "*"
+sympy = "*"
+
+[[package]]
+name = "onnxt5"
+version = "0.1.8"
+description = "Blazing fast summarization, translation, text-generation, Q&A and more using T5 in ONNX"
+optional = false
+python-versions = ">=3.5, <4"
+files = [
+ {file = "onnxt5-0.1.8.tar.gz", hash = "sha256:bba2e5ac9861dd49c7154d26f17330547925704ea8030cb6decd97096a57d539"},
+]
+
+[package.dependencies]
+onnxruntime = ">=1.4.0"
+requests = ">=2.22.0"
+sentencepiece = "*"
+torch = ">=1.4.0"
+tqdm = ">=4.48.2"
+transformers = ">=3.0.2"
+
+[package.extras]
+dev = ["unittest"]
+
+[[package]]
+name = "optimum"
+version = "1.10.0"
+description = "Optimum Library is an extension of the Hugging Face Transformers library, providing a framework to integrate third-party libraries from Hardware Partners and interface with their specific functionality."
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "optimum-1.10.0.tar.gz", hash = "sha256:cc80371dcd38c1748aeb60d6b7b300e81726e95e2c4ccc0e4e53e62a4e36801a"},
+]
+
+[package.dependencies]
+coloredlogs = "*"
+datasets = "*"
+huggingface_hub = ">=0.8.0"
+numpy = "*"
+onnx = {version = "*", optional = true, markers = "extra == \"exporters\""}
+onnxruntime = {version = "*", optional = true, markers = "extra == \"exporters\""}
+packaging = "*"
+sympy = "*"
+timm = {version = "*", optional = true, markers = "extra == \"exporters\""}
+torch = ">=1.9"
+transformers = {version = ">=4.26.0", extras = ["sentencepiece"]}
+
+[package.extras]
+benchmark = ["evaluate (>=0.2.0)", "optuna", "scikit-learn", "seqeval", "torchvision", "tqdm"]
+dev = ["Pillow", "black (>=23.1,<24.0)", "diffusers (>=0.17.0)", "einops", "invisible-watermark", "parameterized", "pytest", "pytest-xdist", "requests", "ruff (>=0.0.241,<=0.0.259)", "sacremoses", "torchaudio", "torchvision"]
+diffusers = ["diffusers"]
+exporters = ["onnx", "onnxruntime", "timm"]
+exporters-gpu = ["onnx", "onnxruntime-gpu", "timm"]
+exporters-tf = ["h5py", "numpy (<1.24.0)", "onnx", "onnxruntime", "tensorflow (>=2.4)", "tf2onnx", "timm"]
+furiosa = ["optimum-furiosa"]
+graphcore = ["optimum-graphcore"]
+habana = ["optimum-habana", "transformers (<4.29.0)"]
+intel = ["optimum-intel"]
+neural-compressor = ["optimum-intel[neural-compressor]"]
+neuron = ["optimum-neuron[neuron]"]
+neuronx = ["optimum-neuron[neuronx]"]
+nncf = ["optimum-intel[nncf]"]
+onnxruntime = ["datasets (>=1.2.1)", "evaluate", "onnx", "onnxruntime (>=1.9.0)", "protobuf (>=3.20.1)"]
+onnxruntime-gpu = ["datasets (>=1.2.1)", "evaluate", "onnx", "onnxruntime-gpu (>=1.9.0)", "protobuf (>=3.20.1)"]
+openvino = ["optimum-intel[openvino]"]
+quality = ["black (>=23.1,<24.0)", "ruff (>=0.0.241,<=0.0.259)"]
+tests = ["Pillow", "diffusers (>=0.17.0)", "einops", "invisible-watermark", "parameterized", "pytest", "pytest-xdist", "requests", "sacremoses", "torchaudio", "torchvision"]
+
+[[package]]
+name = "overrides"
+version = "7.3.1"
+description = "A decorator to automatically detect mismatch when overriding a method."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "overrides-7.3.1-py3-none-any.whl", hash = "sha256:6187d8710a935d09b0bcef8238301d6ee2569d2ac1ae0ec39a8c7924e27f58ca"},
+ {file = "overrides-7.3.1.tar.gz", hash = "sha256:8b97c6c1e1681b78cbc9424b138d880f0803c2254c5ebaabdde57bb6c62093f2"},
+]
+
+[[package]]
+name = "packaging"
+version = "23.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
+ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
+]
+
+[[package]]
+name = "pandas"
+version = "2.0.3"
+description = "Powerful data structures for data analysis, time series, and statistics"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"},
+ {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"},
+ {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"},
+ {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"},
+ {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"},
+ {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"},
+ {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"},
+ {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"},
+ {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"},
+ {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"},
+ {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"},
+ {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"},
+ {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"},
+ {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"},
+ {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"},
+ {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"},
+ {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"},
+ {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"},
+ {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"},
+ {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"},
+ {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"},
+ {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"},
+ {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"},
+ {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"},
+ {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"},
+]
+
+[package.dependencies]
+numpy = [
+ {version = ">=1.20.3", markers = "python_version < \"3.10\""},
+ {version = ">=1.21.0", markers = "python_version >= \"3.10\""},
+ {version = ">=1.23.2", markers = "python_version >= \"3.11\""},
+]
+python-dateutil = ">=2.8.2"
+pytz = ">=2020.1"
+tzdata = ">=2022.1"
+
+[package.extras]
+all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"]
+aws = ["s3fs (>=2021.08.0)"]
+clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"]
+compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"]
+computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"]
+excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"]
+feather = ["pyarrow (>=7.0.0)"]
+fss = ["fsspec (>=2021.07.0)"]
+gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"]
+hdf5 = ["tables (>=3.6.1)"]
+html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"]
+mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"]
+output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"]
+parquet = ["pyarrow (>=7.0.0)"]
+performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"]
+plot = ["matplotlib (>=3.6.1)"]
+postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"]
+spss = ["pyreadstat (>=1.1.2)"]
+sql-other = ["SQLAlchemy (>=1.4.16)"]
+test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"]
+xml = ["lxml (>=4.6.3)"]
+
+[[package]]
+name = "pandocfilters"
+version = "1.5.0"
+description = "Utilities for writing pandoc filters in python"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"},
+ {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"},
+]
+
+[[package]]
+name = "parso"
+version = "0.8.3"
+description = "A Python Parser"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
+ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
+]
+
+[package.extras]
+qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
+testing = ["docopt", "pytest (<6.0.0)"]
+
+[[package]]
+name = "pexpect"
+version = "4.8.0"
+description = "Pexpect allows easy control of interactive console applications."
+optional = false
+python-versions = "*"
+files = [
+ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
+ {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
+]
+
+[package.dependencies]
+ptyprocess = ">=0.5"
+
+[[package]]
+name = "pickleshare"
+version = "0.7.5"
+description = "Tiny 'shelve'-like database with concurrency support"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
+ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
+]
+
+[[package]]
+name = "pillow"
+version = "10.0.0"
+description = "Python Imaging Library (Fork)"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"},
+ {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"},
+ {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"},
+ {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"},
+ {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"},
+ {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"},
+ {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"},
+ {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"},
+ {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"},
+ {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"},
+ {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"},
+ {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"},
+ {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"},
+ {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"},
+ {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"},
+ {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"},
+ {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"},
+ {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"},
+ {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"},
+ {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"},
+ {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"},
+ {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"},
+ {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"},
+ {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"},
+ {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"},
+ {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"},
+ {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"},
+ {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"},
+ {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"},
+ {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"},
+ {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"},
+ {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"},
+ {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"},
+ {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"},
+ {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"},
+ {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"},
+ {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"},
+ {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"},
+ {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"},
+ {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"},
+ {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"},
+ {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"},
+ {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"},
+ {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"},
+ {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"},
+ {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"},
+ {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"},
+ {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"},
+ {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"},
+ {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"},
+ {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"},
+ {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"},
+ {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"},
+ {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"},
+ {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"},
+ {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"},
+]
+
+[package.extras]
+docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"]
+tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
+
+[[package]]
+name = "pkgutil-resolve-name"
+version = "1.3.10"
+description = "Resolve a name to an object."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"},
+ {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"},
+]
+
+[[package]]
+name = "platformdirs"
+version = "3.9.1"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "platformdirs-3.9.1-py3-none-any.whl", hash = "sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"},
+ {file = "platformdirs-3.9.1.tar.gz", hash = "sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"},
+]
+
+[package.extras]
+docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
+
+[[package]]
+name = "prometheus-client"
+version = "0.17.1"
+description = "Python client for the Prometheus monitoring system."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "prometheus_client-0.17.1-py3-none-any.whl", hash = "sha256:e537f37160f6807b8202a6fc4764cdd19bac5480ddd3e0d463c3002b34462101"},
+ {file = "prometheus_client-0.17.1.tar.gz", hash = "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091"},
+]
+
+[package.extras]
+twisted = ["twisted"]
+
+[[package]]
+name = "prompt-toolkit"
+version = "3.0.39"
+description = "Library for building powerful interactive command lines in Python"
+optional = false
+python-versions = ">=3.7.0"
+files = [
+ {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"},
+ {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"},
+]
+
+[package.dependencies]
+wcwidth = "*"
+
+[[package]]
+name = "protobuf"
+version = "4.23.4"
+description = ""
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "protobuf-4.23.4-cp310-abi3-win32.whl", hash = "sha256:5fea3c64d41ea5ecf5697b83e41d09b9589e6f20b677ab3c48e5f242d9b7897b"},
+ {file = "protobuf-4.23.4-cp310-abi3-win_amd64.whl", hash = "sha256:7b19b6266d92ca6a2a87effa88ecc4af73ebc5cfde194dc737cf8ef23a9a3b12"},
+ {file = "protobuf-4.23.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8547bf44fe8cec3c69e3042f5c4fb3e36eb2a7a013bb0a44c018fc1e427aafbd"},
+ {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fee88269a090ada09ca63551bf2f573eb2424035bcf2cb1b121895b01a46594a"},
+ {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:effeac51ab79332d44fba74660d40ae79985901ac21bca408f8dc335a81aa597"},
+ {file = "protobuf-4.23.4-cp37-cp37m-win32.whl", hash = "sha256:c3e0939433c40796ca4cfc0fac08af50b00eb66a40bbbc5dee711998fb0bbc1e"},
+ {file = "protobuf-4.23.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9053df6df8e5a76c84339ee4a9f5a2661ceee4a0dab019e8663c50ba324208b0"},
+ {file = "protobuf-4.23.4-cp38-cp38-win32.whl", hash = "sha256:e1c915778d8ced71e26fcf43c0866d7499891bca14c4368448a82edc61fdbc70"},
+ {file = "protobuf-4.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:351cc90f7d10839c480aeb9b870a211e322bf05f6ab3f55fcb2f51331f80a7d2"},
+ {file = "protobuf-4.23.4-cp39-cp39-win32.whl", hash = "sha256:6dd9b9940e3f17077e820b75851126615ee38643c2c5332aa7a359988820c720"},
+ {file = "protobuf-4.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:0a5759f5696895de8cc913f084e27fd4125e8fb0914bb729a17816a33819f474"},
+ {file = "protobuf-4.23.4-py3-none-any.whl", hash = "sha256:e9d0be5bf34b275b9f87ba7407796556abeeba635455d036c7351f7c183ef8ff"},
+ {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"},
+]
+
+[[package]]
+name = "psutil"
+version = "5.9.5"
+description = "Cross-platform lib for process and system monitoring in Python."
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"},
+ {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"},
+ {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"},
+ {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"},
+ {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"},
+ {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"},
+ {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"},
+ {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"},
+ {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"},
+ {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"},
+ {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"},
+ {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"},
+ {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"},
+ {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"},
+]
+
+[package.extras]
+test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"]
+
+[[package]]
+name = "ptyprocess"
+version = "0.7.0"
+description = "Run a subprocess in a pseudo terminal"
+optional = false
+python-versions = "*"
+files = [
+ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
+ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
+]
+
+[[package]]
+name = "pure-eval"
+version = "0.2.2"
+description = "Safely evaluate AST nodes without side effects"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"},
+ {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"},
+]
+
+[package.extras]
+tests = ["pytest"]
+
+[[package]]
+name = "pyarrow"
+version = "12.0.1"
+description = "Python library for Apache Arrow"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pyarrow-12.0.1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d288029a94a9bb5407ceebdd7110ba398a00412c5b0155ee9813a40d246c5df"},
+ {file = "pyarrow-12.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345e1828efdbd9aa4d4de7d5676778aba384a2c3add896d995b23d368e60e5af"},
+ {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d6009fdf8986332b2169314da482baed47ac053311c8934ac6651e614deacd6"},
+ {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d3c4cbbf81e6dd23fe921bc91dc4619ea3b79bc58ef10bce0f49bdafb103daf"},
+ {file = "pyarrow-12.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdacf515ec276709ac8042c7d9bd5be83b4f5f39c6c037a17a60d7ebfd92c890"},
+ {file = "pyarrow-12.0.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:749be7fd2ff260683f9cc739cb862fb11be376de965a2a8ccbf2693b098db6c7"},
+ {file = "pyarrow-12.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6895b5fb74289d055c43db3af0de6e16b07586c45763cb5e558d38b86a91e3a7"},
+ {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1887bdae17ec3b4c046fcf19951e71b6a619f39fa674f9881216173566c8f718"},
+ {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2c9cb8eeabbadf5fcfc3d1ddea616c7ce893db2ce4dcef0ac13b099ad7ca082"},
+ {file = "pyarrow-12.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ce4aebdf412bd0eeb800d8e47db854f9f9f7e2f5a0220440acf219ddfddd4f63"},
+ {file = "pyarrow-12.0.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:e0d8730c7f6e893f6db5d5b86eda42c0a130842d101992b581e2138e4d5663d3"},
+ {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43364daec02f69fec89d2315f7fbfbeec956e0d991cbbef471681bd77875c40f"},
+ {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051f9f5ccf585f12d7de836e50965b3c235542cc896959320d9776ab93f3b33d"},
+ {file = "pyarrow-12.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:be2757e9275875d2a9c6e6052ac7957fbbfc7bc7370e4a036a9b893e96fedaba"},
+ {file = "pyarrow-12.0.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:cf812306d66f40f69e684300f7af5111c11f6e0d89d6b733e05a3de44961529d"},
+ {file = "pyarrow-12.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:459a1c0ed2d68671188b2118c63bac91eaef6fc150c77ddd8a583e3c795737bf"},
+ {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e705e33eaf666bbe508a16fd5ba27ca061e177916b7a317ba5a51bee43384c"},
+ {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9120c3eb2b1f6f516a3b7a9714ed860882d9ef98c4b17edcdc91d95b7528db60"},
+ {file = "pyarrow-12.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c780f4dc40460015d80fcd6a6140de80b615349ed68ef9adb653fe351778c9b3"},
+ {file = "pyarrow-12.0.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a3c63124fc26bf5f95f508f5d04e1ece8cc23a8b0af2a1e6ab2b1ec3fdc91b24"},
+ {file = "pyarrow-12.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b13329f79fa4472324f8d32dc1b1216616d09bd1e77cfb13104dec5463632c36"},
+ {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb656150d3d12ec1396f6dde542db1675a95c0cc8366d507347b0beed96e87ca"},
+ {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6251e38470da97a5b2e00de5c6a049149f7b2bd62f12fa5dbb9ac674119ba71a"},
+ {file = "pyarrow-12.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:3de26da901216149ce086920547dfff5cd22818c9eab67ebc41e863a5883bac7"},
+ {file = "pyarrow-12.0.1.tar.gz", hash = "sha256:cce317fc96e5b71107bf1f9f184d5e54e2bd14bbf3f9a3d62819961f0af86fec"},
+]
+
+[package.dependencies]
+numpy = ">=1.16.6"
+
+[[package]]
+name = "pycparser"
+version = "2.21"
+description = "C parser in Python"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
+ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
+]
+
+[[package]]
+name = "pydot"
+version = "1.4.2"
+description = "Python interface to Graphviz's Dot"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "pydot-1.4.2-py2.py3-none-any.whl", hash = "sha256:66c98190c65b8d2e2382a441b4c0edfdb4f4c025ef9cb9874de478fb0793a451"},
+ {file = "pydot-1.4.2.tar.gz", hash = "sha256:248081a39bcb56784deb018977e428605c1c758f10897a339fce1dd728ff007d"},
+]
+
+[package.dependencies]
+pyparsing = ">=2.1.4"
+
+[[package]]
+name = "pygments"
+version = "2.15.1"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"},
+ {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"},
+]
+
+[package.extras]
+plugins = ["importlib-metadata"]
+
+[[package]]
+name = "pygraphviz"
+version = "1.11"
+description = "Python interface to Graphviz"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "pygraphviz-1.11.zip", hash = "sha256:a97eb5ced266f45053ebb1f2c6c6d29091690503e3a5c14be7f908b37b06f2d4"},
+]
+
+[[package]]
+name = "pyparsing"
+version = "3.0.9"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.6.8"
+files = [
+ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
+ {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
+[[package]]
+name = "pyreadline3"
+version = "3.4.1"
+description = "A python implementation of GNU readline."
+optional = false
+python-versions = "*"
+files = [
+ {file = "pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb"},
+ {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"},
+]
+
+[[package]]
+name = "python-dateutil"
+version = "2.8.2"
+description = "Extensions to the standard Python datetime module"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
+files = [
+ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
+ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
+]
+
+[package.dependencies]
+six = ">=1.5"
+
+[[package]]
+name = "python-json-logger"
+version = "2.0.7"
+description = "A python library adding a json log formatter"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"},
+ {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"},
+]
+
+[[package]]
+name = "pytz"
+version = "2023.3"
+description = "World timezone definitions, modern and historical"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
+ {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
+]
+
+[[package]]
+name = "pywin32"
+version = "306"
+description = "Python for Window Extensions"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"},
+ {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"},
+ {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"},
+ {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"},
+ {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"},
+ {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"},
+ {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"},
+ {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"},
+ {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"},
+ {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"},
+ {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"},
+ {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"},
+ {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"},
+ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"},
+]
+
+[[package]]
+name = "pywinpty"
+version = "2.0.11"
+description = "Pseudo terminal support for Windows from Python."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "pywinpty-2.0.11-cp310-none-win_amd64.whl", hash = "sha256:452f10ac9ff8ab9151aa8cea9e491a9612a12250b1899278c6a56bc184afb47f"},
+ {file = "pywinpty-2.0.11-cp311-none-win_amd64.whl", hash = "sha256:6701867d42aec1239bc0fedf49a336570eb60eb886e81763db77ea2b6c533cc3"},
+ {file = "pywinpty-2.0.11-cp38-none-win_amd64.whl", hash = "sha256:0ffd287751ad871141dc9724de70ea21f7fc2ff1af50861e0d232cf70739d8c4"},
+ {file = "pywinpty-2.0.11-cp39-none-win_amd64.whl", hash = "sha256:e4e7f023c28ca7aa8e1313e53ba80a4d10171fe27857b7e02f99882dfe3e8638"},
+ {file = "pywinpty-2.0.11.tar.gz", hash = "sha256:e244cffe29a894876e2cd251306efd0d8d64abd5ada0a46150a4a71c0b9ad5c5"},
+]
+
+[[package]]
+name = "pyyaml"
+version = "6.0.1"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
+ {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
+ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
+ {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
+ {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
+ {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
+ {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
+ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
+ {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
+ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
+ {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
+ {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
+ {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
+ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
+ {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
+ {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
+ {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
+ {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
+ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
+ {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
+ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
+]
+
+[[package]]
+name = "pyzmq"
+version = "25.1.0"
+description = "Python bindings for 0MQ"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:1a6169e69034eaa06823da6a93a7739ff38716142b3596c180363dee729d713d"},
+ {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:19d0383b1f18411d137d891cab567de9afa609b214de68b86e20173dc624c101"},
+ {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1e931d9a92f628858a50f5bdffdfcf839aebe388b82f9d2ccd5d22a38a789dc"},
+ {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97d984b1b2f574bc1bb58296d3c0b64b10e95e7026f8716ed6c0b86d4679843f"},
+ {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:154bddda2a351161474b36dba03bf1463377ec226a13458725183e508840df89"},
+ {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cb6d161ae94fb35bb518b74bb06b7293299c15ba3bc099dccd6a5b7ae589aee3"},
+ {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:90146ab578931e0e2826ee39d0c948d0ea72734378f1898939d18bc9c823fcf9"},
+ {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:831ba20b660b39e39e5ac8603e8193f8fce1ee03a42c84ade89c36a251449d80"},
+ {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3a522510e3434e12aff80187144c6df556bb06fe6b9d01b2ecfbd2b5bfa5c60c"},
+ {file = "pyzmq-25.1.0-cp310-cp310-win32.whl", hash = "sha256:be24a5867b8e3b9dd5c241de359a9a5217698ff616ac2daa47713ba2ebe30ad1"},
+ {file = "pyzmq-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:5693dcc4f163481cf79e98cf2d7995c60e43809e325b77a7748d8024b1b7bcba"},
+ {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:13bbe36da3f8aaf2b7ec12696253c0bf6ffe05f4507985a8844a1081db6ec22d"},
+ {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:69511d604368f3dc58d4be1b0bad99b61ee92b44afe1cd9b7bd8c5e34ea8248a"},
+ {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a983c8694667fd76d793ada77fd36c8317e76aa66eec75be2653cef2ea72883"},
+ {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:332616f95eb400492103ab9d542b69d5f0ff628b23129a4bc0a2fd48da6e4e0b"},
+ {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58416db767787aedbfd57116714aad6c9ce57215ffa1c3758a52403f7c68cff5"},
+ {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cad9545f5801a125f162d09ec9b724b7ad9b6440151b89645241d0120e119dcc"},
+ {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d6128d431b8dfa888bf51c22a04d48bcb3d64431caf02b3cb943269f17fd2994"},
+ {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b15247c49d8cbea695b321ae5478d47cffd496a2ec5ef47131a9e79ddd7e46c"},
+ {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:442d3efc77ca4d35bee3547a8e08e8d4bb88dadb54a8377014938ba98d2e074a"},
+ {file = "pyzmq-25.1.0-cp311-cp311-win32.whl", hash = "sha256:65346f507a815a731092421d0d7d60ed551a80d9b75e8b684307d435a5597425"},
+ {file = "pyzmq-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b45d722046fea5a5694cba5d86f21f78f0052b40a4bbbbf60128ac55bfcc7b6"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f45808eda8b1d71308c5416ef3abe958f033fdbb356984fabbfc7887bed76b3f"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b697774ea8273e3c0460cf0bba16cd85ca6c46dfe8b303211816d68c492e132"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b324fa769577fc2c8f5efcd429cef5acbc17d63fe15ed16d6dcbac2c5eb00849"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5873d6a60b778848ce23b6c0ac26c39e48969823882f607516b91fb323ce80e5"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f0d9e7ba6a815a12c8575ba7887da4b72483e4cfc57179af10c9b937f3f9308f"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:414b8beec76521358b49170db7b9967d6974bdfc3297f47f7d23edec37329b00"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:01f06f33e12497dca86353c354461f75275a5ad9eaea181ac0dc1662da8074fa"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-win32.whl", hash = "sha256:b5a07c4f29bf7cb0164664ef87e4aa25435dcc1f818d29842118b0ac1eb8e2b5"},
+ {file = "pyzmq-25.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:968b0c737797c1809ec602e082cb63e9824ff2329275336bb88bd71591e94a90"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47b915ba666c51391836d7ed9a745926b22c434efa76c119f77bcffa64d2c50c"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5af31493663cf76dd36b00dafbc839e83bbca8a0662931e11816d75f36155897"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5489738a692bc7ee9a0a7765979c8a572520d616d12d949eaffc6e061b82b4d1"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1fc56a0221bdf67cfa94ef2d6ce5513a3d209c3dfd21fed4d4e87eca1822e3a3"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:75217e83faea9edbc29516fc90c817bc40c6b21a5771ecb53e868e45594826b0"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3830be8826639d801de9053cf86350ed6742c4321ba4236e4b5568528d7bfed7"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3575699d7fd7c9b2108bc1c6128641a9a825a58577775ada26c02eb29e09c517"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-win32.whl", hash = "sha256:95bd3a998d8c68b76679f6b18f520904af5204f089beebb7b0301d97704634dd"},
+ {file = "pyzmq-25.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:dbc466744a2db4b7ca05589f21ae1a35066afada2f803f92369f5877c100ef62"},
+ {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:3bed53f7218490c68f0e82a29c92335daa9606216e51c64f37b48eb78f1281f4"},
+ {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eb52e826d16c09ef87132c6e360e1879c984f19a4f62d8a935345deac43f3c12"},
+ {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ddbef8b53cd16467fdbfa92a712eae46dd066aa19780681a2ce266e88fbc7165"},
+ {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9301cf1d7fc1ddf668d0abbe3e227fc9ab15bc036a31c247276012abb921b5ff"},
+ {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e23a8c3b6c06de40bdb9e06288180d630b562db8ac199e8cc535af81f90e64b"},
+ {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4a82faae00d1eed4809c2f18b37f15ce39a10a1c58fe48b60ad02875d6e13d80"},
+ {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8398a1b1951aaa330269c35335ae69744be166e67e0ebd9869bdc09426f3871"},
+ {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d40682ac60b2a613d36d8d3a0cd14fbdf8e7e0618fbb40aa9fa7b796c9081584"},
+ {file = "pyzmq-25.1.0-cp38-cp38-win32.whl", hash = "sha256:33d5c8391a34d56224bccf74f458d82fc6e24b3213fc68165c98b708c7a69325"},
+ {file = "pyzmq-25.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c66b7ff2527e18554030319b1376d81560ca0742c6e0b17ff1ee96624a5f1afd"},
+ {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:af56229ea6527a849ac9fb154a059d7e32e77a8cba27e3e62a1e38d8808cb1a5"},
+ {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bdca18b94c404af6ae5533cd1bc310c4931f7ac97c148bbfd2cd4bdd62b96253"},
+ {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b6b42f7055bbc562f63f3df3b63e3dd1ebe9727ff0f124c3aa7bcea7b3a00f9"},
+ {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c2fc7aad520a97d64ffc98190fce6b64152bde57a10c704b337082679e74f67"},
+ {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be86a26415a8b6af02cd8d782e3a9ae3872140a057f1cadf0133de685185c02b"},
+ {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:851fb2fe14036cfc1960d806628b80276af5424db09fe5c91c726890c8e6d943"},
+ {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2a21fec5c3cea45421a19ccbe6250c82f97af4175bc09de4d6dd78fb0cb4c200"},
+ {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bad172aba822444b32eae54c2d5ab18cd7dee9814fd5c7ed026603b8cae2d05f"},
+ {file = "pyzmq-25.1.0-cp39-cp39-win32.whl", hash = "sha256:4d67609b37204acad3d566bb7391e0ecc25ef8bae22ff72ebe2ad7ffb7847158"},
+ {file = "pyzmq-25.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:71c7b5896e40720d30cd77a81e62b433b981005bbff0cb2f739e0f8d059b5d99"},
+ {file = "pyzmq-25.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cb27ef9d3bdc0c195b2dc54fcb8720e18b741624686a81942e14c8b67cc61a6"},
+ {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0c4fc2741e0513b5d5a12fe200d6785bbcc621f6f2278893a9ca7bed7f2efb7d"},
+ {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fc34fdd458ff77a2a00e3c86f899911f6f269d393ca5675842a6e92eea565bae"},
+ {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8751f9c1442624da391bbd92bd4b072def6d7702a9390e4479f45c182392ff78"},
+ {file = "pyzmq-25.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6581e886aec3135964a302a0f5eb68f964869b9efd1dbafdebceaaf2934f8a68"},
+ {file = "pyzmq-25.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5482f08d2c3c42b920e8771ae8932fbaa0a67dff925fc476996ddd8155a170f3"},
+ {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7fbcafa3ea16d1de1f213c226005fea21ee16ed56134b75b2dede5a2129e62"},
+ {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:adecf6d02b1beab8d7c04bc36f22bb0e4c65a35eb0b4750b91693631d4081c70"},
+ {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6d39e42a0aa888122d1beb8ec0d4ddfb6c6b45aecb5ba4013c27e2f28657765"},
+ {file = "pyzmq-25.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7018289b402ebf2b2c06992813523de61d4ce17bd514c4339d8f27a6f6809492"},
+ {file = "pyzmq-25.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9e68ae9864d260b18f311b68d29134d8776d82e7f5d75ce898b40a88df9db30f"},
+ {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e21cc00e4debe8f54c3ed7b9fcca540f46eee12762a9fa56feb8512fd9057161"},
+ {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f666ae327a6899ff560d741681fdcdf4506f990595201ed39b44278c471ad98"},
+ {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f5efcc29056dfe95e9c9db0dfbb12b62db9c4ad302f812931b6d21dd04a9119"},
+ {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:48e5e59e77c1a83162ab3c163fc01cd2eebc5b34560341a67421b09be0891287"},
+ {file = "pyzmq-25.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:108c96ebbd573d929740d66e4c3d1bdf31d5cde003b8dc7811a3c8c5b0fc173b"},
+ {file = "pyzmq-25.1.0.tar.gz", hash = "sha256:80c41023465d36280e801564a69cbfce8ae85ff79b080e1913f6e90481fb8957"},
+]
+
+[package.dependencies]
+cffi = {version = "*", markers = "implementation_name == \"pypy\""}
+
+[[package]]
+name = "qtconsole"
+version = "5.4.3"
+description = "Jupyter Qt console"
+optional = false
+python-versions = ">= 3.7"
+files = [
+ {file = "qtconsole-5.4.3-py3-none-any.whl", hash = "sha256:35fd6e87b1f6d1fd41801b07e69339f8982e76afd4fa8ef35595bc6036717189"},
+ {file = "qtconsole-5.4.3.tar.gz", hash = "sha256:5e4082a86a201796b2a5cfd4298352d22b158b51b57736531824715fc2a979dd"},
+]
+
+[package.dependencies]
+ipykernel = ">=4.1"
+ipython-genutils = "*"
+jupyter-client = ">=4.1"
+jupyter-core = "*"
+packaging = "*"
+pygments = "*"
+pyzmq = ">=17.1"
+qtpy = ">=2.0.1"
+traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2"
+
+[package.extras]
+doc = ["Sphinx (>=1.3)"]
+test = ["flaky", "pytest", "pytest-qt"]
+
+[[package]]
+name = "qtpy"
+version = "2.3.1"
+description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "QtPy-2.3.1-py3-none-any.whl", hash = "sha256:5193d20e0b16e4d9d3bc2c642d04d9f4e2c892590bd1b9c92bfe38a95d5a2e12"},
+ {file = "QtPy-2.3.1.tar.gz", hash = "sha256:a8c74982d6d172ce124d80cafd39653df78989683f760f2281ba91a6e7b9de8b"},
+]
+
+[package.dependencies]
+packaging = "*"
+
+[package.extras]
+test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"]
+
+[[package]]
+name = "referencing"
+version = "0.30.0"
+description = "JSON Referencing + Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "referencing-0.30.0-py3-none-any.whl", hash = "sha256:c257b08a399b6c2f5a3510a50d28ab5dbc7bbde049bcaf954d43c446f83ab548"},
+ {file = "referencing-0.30.0.tar.gz", hash = "sha256:47237742e990457f7512c7d27486394a9aadaf876cbfaa4be65b27b4f4d47c6b"},
+]
+
+[package.dependencies]
+attrs = ">=22.2.0"
+rpds-py = ">=0.7.0"
+
+[[package]]
+name = "regex"
+version = "2023.6.3"
+description = "Alternative regular expression module, to replace re."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "regex-2023.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:824bf3ac11001849aec3fa1d69abcb67aac3e150a933963fb12bda5151fe1bfd"},
+ {file = "regex-2023.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05ed27acdf4465c95826962528f9e8d41dbf9b1aa8531a387dee6ed215a3e9ef"},
+ {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b49c764f88a79160fa64f9a7b425620e87c9f46095ef9c9920542ab2495c8bc"},
+ {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e3f1316c2293e5469f8f09dc2d76efb6c3982d3da91ba95061a7e69489a14ef"},
+ {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43e1dd9d12df9004246bacb79a0e5886b3b6071b32e41f83b0acbf293f820ee8"},
+ {file = "regex-2023.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4959e8bcbfda5146477d21c3a8ad81b185cd252f3d0d6e4724a5ef11c012fb06"},
+ {file = "regex-2023.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af4dd387354dc83a3bff67127a124c21116feb0d2ef536805c454721c5d7993d"},
+ {file = "regex-2023.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2239d95d8e243658b8dbb36b12bd10c33ad6e6933a54d36ff053713f129aa536"},
+ {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:890e5a11c97cf0d0c550eb661b937a1e45431ffa79803b942a057c4fb12a2da2"},
+ {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a8105e9af3b029f243ab11ad47c19b566482c150c754e4c717900a798806b222"},
+ {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:25be746a8ec7bc7b082783216de8e9473803706723b3f6bef34b3d0ed03d57e2"},
+ {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:3676f1dd082be28b1266c93f618ee07741b704ab7b68501a173ce7d8d0d0ca18"},
+ {file = "regex-2023.6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:10cb847aeb1728412c666ab2e2000ba6f174f25b2bdc7292e7dd71b16db07568"},
+ {file = "regex-2023.6.3-cp310-cp310-win32.whl", hash = "sha256:dbbbfce33cd98f97f6bffb17801b0576e653f4fdb1d399b2ea89638bc8d08ae1"},
+ {file = "regex-2023.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:c5f8037000eb21e4823aa485149f2299eb589f8d1fe4b448036d230c3f4e68e0"},
+ {file = "regex-2023.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c123f662be8ec5ab4ea72ea300359023a5d1df095b7ead76fedcd8babbedf969"},
+ {file = "regex-2023.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9edcbad1f8a407e450fbac88d89e04e0b99a08473f666a3f3de0fd292badb6aa"},
+ {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcba6dae7de533c876255317c11f3abe4907ba7d9aa15d13e3d9710d4315ec0e"},
+ {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29cdd471ebf9e0f2fb3cac165efedc3c58db841d83a518b082077e612d3ee5df"},
+ {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12b74fbbf6cbbf9dbce20eb9b5879469e97aeeaa874145517563cca4029db65c"},
+ {file = "regex-2023.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c29ca1bd61b16b67be247be87390ef1d1ef702800f91fbd1991f5c4421ebae8"},
+ {file = "regex-2023.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77f09bc4b55d4bf7cc5eba785d87001d6757b7c9eec237fe2af57aba1a071d9"},
+ {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ea353ecb6ab5f7e7d2f4372b1e779796ebd7b37352d290096978fea83c4dba0c"},
+ {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:10590510780b7541969287512d1b43f19f965c2ece6c9b1c00fc367b29d8dce7"},
+ {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e2fbd6236aae3b7f9d514312cdb58e6494ee1c76a9948adde6eba33eb1c4264f"},
+ {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:6b2675068c8b56f6bfd5a2bda55b8accbb96c02fd563704732fd1c95e2083461"},
+ {file = "regex-2023.6.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74419d2b50ecb98360cfaa2974da8689cb3b45b9deff0dcf489c0d333bcc1477"},
+ {file = "regex-2023.6.3-cp311-cp311-win32.whl", hash = "sha256:fb5ec16523dc573a4b277663a2b5a364e2099902d3944c9419a40ebd56a118f9"},
+ {file = "regex-2023.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:09e4a1a6acc39294a36b7338819b10baceb227f7f7dbbea0506d419b5a1dd8af"},
+ {file = "regex-2023.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0654bca0cdf28a5956c83839162692725159f4cda8d63e0911a2c0dc76166525"},
+ {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:463b6a3ceb5ca952e66550a4532cef94c9a0c80dc156c4cc343041951aec1697"},
+ {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87b2a5bb5e78ee0ad1de71c664d6eb536dc3947a46a69182a90f4410f5e3f7dd"},
+ {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6343c6928282c1f6a9db41f5fd551662310e8774c0e5ebccb767002fcf663ca9"},
+ {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6192d5af2ccd2a38877bfef086d35e6659566a335b1492786ff254c168b1693"},
+ {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74390d18c75054947e4194019077e243c06fbb62e541d8817a0fa822ea310c14"},
+ {file = "regex-2023.6.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:742e19a90d9bb2f4a6cf2862b8b06dea5e09b96c9f2df1779e53432d7275331f"},
+ {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8abbc5d54ea0ee80e37fef009e3cec5dafd722ed3c829126253d3e22f3846f1e"},
+ {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c2b867c17a7a7ae44c43ebbeb1b5ff406b3e8d5b3e14662683e5e66e6cc868d3"},
+ {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d831c2f8ff278179705ca59f7e8524069c1a989e716a1874d6d1aab6119d91d1"},
+ {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ee2d1a9a253b1729bb2de27d41f696ae893507c7db224436abe83ee25356f5c1"},
+ {file = "regex-2023.6.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:61474f0b41fe1a80e8dfa70f70ea1e047387b7cd01c85ec88fa44f5d7561d787"},
+ {file = "regex-2023.6.3-cp36-cp36m-win32.whl", hash = "sha256:0b71e63226e393b534105fcbdd8740410dc6b0854c2bfa39bbda6b0d40e59a54"},
+ {file = "regex-2023.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bbb02fd4462f37060122e5acacec78e49c0fbb303c30dd49c7f493cf21fc5b27"},
+ {file = "regex-2023.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b862c2b9d5ae38a68b92e215b93f98d4c5e9454fa36aae4450f61dd33ff48487"},
+ {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:976d7a304b59ede34ca2921305b57356694f9e6879db323fd90a80f865d355a3"},
+ {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:83320a09188e0e6c39088355d423aa9d056ad57a0b6c6381b300ec1a04ec3d16"},
+ {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9427a399501818a7564f8c90eced1e9e20709ece36be701f394ada99890ea4b3"},
+ {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178bbc1b2ec40eaca599d13c092079bf529679bf0371c602edaa555e10b41c3"},
+ {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:837328d14cde912af625d5f303ec29f7e28cdab588674897baafaf505341f2fc"},
+ {file = "regex-2023.6.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2d44dc13229905ae96dd2ae2dd7cebf824ee92bc52e8cf03dcead37d926da019"},
+ {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d54af539295392611e7efbe94e827311eb8b29668e2b3f4cadcfe6f46df9c777"},
+ {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7117d10690c38a622e54c432dfbbd3cbd92f09401d622902c32f6d377e2300ee"},
+ {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bb60b503ec8a6e4e3e03a681072fa3a5adcbfa5479fa2d898ae2b4a8e24c4591"},
+ {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:65ba8603753cec91c71de423a943ba506363b0e5c3fdb913ef8f9caa14b2c7e0"},
+ {file = "regex-2023.6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:271f0bdba3c70b58e6f500b205d10a36fb4b58bd06ac61381b68de66442efddb"},
+ {file = "regex-2023.6.3-cp37-cp37m-win32.whl", hash = "sha256:9beb322958aaca059f34975b0df135181f2e5d7a13b84d3e0e45434749cb20f7"},
+ {file = "regex-2023.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fea75c3710d4f31389eed3c02f62d0b66a9da282521075061ce875eb5300cf23"},
+ {file = "regex-2023.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f56fcb7ff7bf7404becdfc60b1e81a6d0561807051fd2f1860b0d0348156a07"},
+ {file = "regex-2023.6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d2da3abc88711bce7557412310dfa50327d5769a31d1c894b58eb256459dc289"},
+ {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99b50300df5add73d307cf66abea093304a07eb017bce94f01e795090dea87c"},
+ {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5708089ed5b40a7b2dc561e0c8baa9535b77771b64a8330b684823cfd5116036"},
+ {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:687ea9d78a4b1cf82f8479cab23678aff723108df3edeac098e5b2498879f4a7"},
+ {file = "regex-2023.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d3850beab9f527f06ccc94b446c864059c57651b3f911fddb8d9d3ec1d1b25d"},
+ {file = "regex-2023.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8915cc96abeb8983cea1df3c939e3c6e1ac778340c17732eb63bb96247b91d2"},
+ {file = "regex-2023.6.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:841d6e0e5663d4c7b4c8099c9997be748677d46cbf43f9f471150e560791f7ff"},
+ {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9edce5281f965cf135e19840f4d93d55b3835122aa76ccacfd389e880ba4cf82"},
+ {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b956231ebdc45f5b7a2e1f90f66a12be9610ce775fe1b1d50414aac1e9206c06"},
+ {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:36efeba71c6539d23c4643be88295ce8c82c88bbd7c65e8a24081d2ca123da3f"},
+ {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:cf67ca618b4fd34aee78740bea954d7c69fdda419eb208c2c0c7060bb822d747"},
+ {file = "regex-2023.6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b4598b1897837067a57b08147a68ac026c1e73b31ef6e36deeeb1fa60b2933c9"},
+ {file = "regex-2023.6.3-cp38-cp38-win32.whl", hash = "sha256:f415f802fbcafed5dcc694c13b1292f07fe0befdb94aa8a52905bd115ff41e88"},
+ {file = "regex-2023.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:d4f03bb71d482f979bda92e1427f3ec9b220e62a7dd337af0aa6b47bf4498f72"},
+ {file = "regex-2023.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ccf91346b7bd20c790310c4147eee6ed495a54ddb6737162a36ce9dbef3e4751"},
+ {file = "regex-2023.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b28f5024a3a041009eb4c333863d7894d191215b39576535c6734cd88b0fcb68"},
+ {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0bb18053dfcfed432cc3ac632b5e5e5c5b7e55fb3f8090e867bfd9b054dbcbf"},
+ {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5bfb3004f2144a084a16ce19ca56b8ac46e6fd0651f54269fc9e230edb5e4a"},
+ {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c6b48d0fa50d8f4df3daf451be7f9689c2bde1a52b1225c5926e3f54b6a9ed1"},
+ {file = "regex-2023.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051da80e6eeb6e239e394ae60704d2b566aa6a7aed6f2890a7967307267a5dc6"},
+ {file = "regex-2023.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4c3b7fa4cdaa69268748665a1a6ff70c014d39bb69c50fda64b396c9116cf77"},
+ {file = "regex-2023.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:457b6cce21bee41ac292d6753d5e94dcbc5c9e3e3a834da285b0bde7aa4a11e9"},
+ {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aad51907d74fc183033ad796dd4c2e080d1adcc4fd3c0fd4fd499f30c03011cd"},
+ {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0385e73da22363778ef2324950e08b689abdf0b108a7d8decb403ad7f5191938"},
+ {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a57b742133830eec44d9b2290daf5cbe0a2f1d6acee1b3c7b1c7b2f3606df7"},
+ {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3e5219bf9e75993d73ab3d25985c857c77e614525fac9ae02b1bebd92f7cecac"},
+ {file = "regex-2023.6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e5087a3c59eef624a4591ef9eaa6e9a8d8a94c779dade95d27c0bc24650261cd"},
+ {file = "regex-2023.6.3-cp39-cp39-win32.whl", hash = "sha256:20326216cc2afe69b6e98528160b225d72f85ab080cbdf0b11528cbbaba2248f"},
+ {file = "regex-2023.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:bdff5eab10e59cf26bc479f565e25ed71a7d041d1ded04ccf9aee1d9f208487a"},
+ {file = "regex-2023.6.3.tar.gz", hash = "sha256:72d1a25bf36d2050ceb35b517afe13864865268dfb45910e2e17a84be6cbfeb0"},
+]
+
+[[package]]
+name = "requests"
+version = "2.31.0"
+description = "Python HTTP for Humans."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
+ {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+]
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<3"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
+[[package]]
+name = "rfc3339-validator"
+version = "0.1.4"
+description = "A pure python RFC3339 validator"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"},
+ {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"},
+]
+
+[package.dependencies]
+six = "*"
+
+[[package]]
+name = "rfc3986-validator"
+version = "0.1.1"
+description = "Pure python rfc3986 validator"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"},
+ {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"},
+]
+
+[[package]]
+name = "rpds-py"
+version = "0.9.2"
+description = "Python bindings to Rust's persistent data structures (rpds)"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"},
+ {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"},
+ {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"},
+ {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"},
+ {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"},
+ {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"},
+ {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"},
+ {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"},
+ {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"},
+ {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"},
+ {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"},
+ {file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"},
+ {file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"},
+ {file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"},
+ {file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"},
+ {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"},
+ {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"},
+ {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"},
+ {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"},
+ {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"},
+ {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"},
+ {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"},
+ {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"},
+ {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"},
+ {file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"},
+ {file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"},
+ {file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"},
+ {file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"},
+ {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"},
+ {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"},
+ {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"},
+ {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"},
+ {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"},
+ {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"},
+ {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"},
+ {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"},
+ {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"},
+ {file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"},
+ {file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"},
+ {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"},
+ {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"},
+ {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"},
+ {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"},
+ {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"},
+ {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"},
+ {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"},
+ {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"},
+ {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"},
+ {file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"},
+ {file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"},
+ {file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"},
+ {file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"},
+ {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"},
+ {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"},
+ {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"},
+ {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"},
+ {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"},
+ {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"},
+ {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"},
+ {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"},
+ {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"},
+ {file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"},
+ {file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"},
+ {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"},
+ {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"},
+ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"},
+ {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"},
+]
+
+[[package]]
+name = "safetensors"
+version = "0.3.1"
+description = "Fast and Safe Tensor serialization"
+optional = false
+python-versions = "*"
+files = [
+ {file = "safetensors-0.3.1-cp310-cp310-macosx_10_11_x86_64.whl", hash = "sha256:2ae9b7dd268b4bae6624729dac86deb82104820e9786429b0583e5168db2f770"},
+ {file = "safetensors-0.3.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:08c85c1934682f1e2cd904d38433b53cd2a98245a7cc31f5689f9322a2320bbf"},
+ {file = "safetensors-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba625c7af9e1c5d0d91cb83d2fba97d29ea69d4db2015d9714d24c7f6d488e15"},
+ {file = "safetensors-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b57d5890c619ec10d9f1b6426b8690d0c9c2868a90dc52f13fae6f6407ac141f"},
+ {file = "safetensors-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c9f562ea696d50b95cadbeb1716dc476714a87792ffe374280c0835312cbfe2"},
+ {file = "safetensors-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c115951b3a865ece8d98ee43882f2fd0a999c0200d6e6fec24134715ebe3b57"},
+ {file = "safetensors-0.3.1-cp310-cp310-win32.whl", hash = "sha256:118f8f7503ea312fc7af27e934088a1b589fb1eff5a7dea2cd1de6c71ee33391"},
+ {file = "safetensors-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:54846eaae25fded28a7bebbb66be563cad221b4c80daee39e2f55df5e5e0266f"},
+ {file = "safetensors-0.3.1-cp311-cp311-macosx_10_11_universal2.whl", hash = "sha256:5af82e10946c4822506db0f29269f43147e889054704dde994d4e22f0c37377b"},
+ {file = "safetensors-0.3.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:626c86dd1d930963c8ea7f953a3787ae85322551e3a5203ac731d6e6f3e18f44"},
+ {file = "safetensors-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12e30677e6af1f4cc4f2832546e91dbb3b0aa7d575bfa473d2899d524e1ace08"},
+ {file = "safetensors-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d534b80bc8d39945bb902f34b0454773971fe9e5e1f2142af451759d7e52b356"},
+ {file = "safetensors-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ddd0ddd502cf219666e7d30f23f196cb87e829439b52b39f3e7da7918c3416df"},
+ {file = "safetensors-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997a2cc14023713f423e6d16536d55cb16a3d72850f142e05f82f0d4c76d383b"},
+ {file = "safetensors-0.3.1-cp311-cp311-win32.whl", hash = "sha256:6ae9ca63d9e22f71ec40550207bd284a60a6b4916ae6ca12c85a8d86bf49e0c3"},
+ {file = "safetensors-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:62aa7421ca455418423e35029524489480adda53e3f702453580180ecfebe476"},
+ {file = "safetensors-0.3.1-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:6d54b3ed367b6898baab75dfd057c24f36ec64d3938ffff2af981d56bfba2f42"},
+ {file = "safetensors-0.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:262423aeda91117010f8c607889066028f680fbb667f50cfe6eae96f22f9d150"},
+ {file = "safetensors-0.3.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10efe2513a8327fd628cea13167089588acc23093ba132aecfc536eb9a4560fe"},
+ {file = "safetensors-0.3.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:689b3d6a7ebce70ee9438267ee55ea89b575c19923876645e927d08757b552fe"},
+ {file = "safetensors-0.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14cd9a87bc73ce06903e9f8ee8b05b056af6f3c9f37a6bd74997a16ed36ff5f4"},
+ {file = "safetensors-0.3.1-cp37-cp37m-win32.whl", hash = "sha256:a77cb39624480d5f143c1cc272184f65a296f573d61629eff5d495d2e0541d3e"},
+ {file = "safetensors-0.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9eff3190bfbbb52eef729911345c643f875ca4dbb374aa6c559675cfd0ab73db"},
+ {file = "safetensors-0.3.1-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:05cbfef76e4daa14796db1bbb52072d4b72a44050c368b2b1f6fd3e610669a89"},
+ {file = "safetensors-0.3.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:c49061461f4a81e5ec3415070a3f135530834c89cbd6a7db7cd49e3cb9d9864b"},
+ {file = "safetensors-0.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22cf7e73ca42974f098ce0cf4dd8918983700b6b07a4c6827d50c8daefca776e"},
+ {file = "safetensors-0.3.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04f909442d6223ff0016cd2e1b2a95ef8039b92a558014627363a2e267213f62"},
+ {file = "safetensors-0.3.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c573c5a0d5d45791ae8c179e26d74aff86e719056591aa7edb3ca7be55bc961"},
+ {file = "safetensors-0.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6994043b12e717cf2a6ba69077ac41f0d3675b2819734f07f61819e854c622c7"},
+ {file = "safetensors-0.3.1-cp38-cp38-win32.whl", hash = "sha256:158ede81694180a0dbba59422bc304a78c054b305df993c0c6e39c6330fa9348"},
+ {file = "safetensors-0.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:afdc725beff7121ea8d39a7339f5a6abcb01daa189ea56290b67fe262d56e20f"},
+ {file = "safetensors-0.3.1-cp39-cp39-macosx_10_11_x86_64.whl", hash = "sha256:cba910fcc9e5e64d32d62b837388721165e9c7e45d23bc3a38ad57694b77f40d"},
+ {file = "safetensors-0.3.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a4f7dbfe7285573cdaddd85ef6fa84ebbed995d3703ab72d71257944e384612f"},
+ {file = "safetensors-0.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54aed0802f9eaa83ca7b1cbb986bfb90b8e2c67b6a4bcfe245627e17dad565d4"},
+ {file = "safetensors-0.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34b75a766f3cfc99fd4c33e329b76deae63f5f388e455d863a5d6e99472fca8e"},
+ {file = "safetensors-0.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a0f31904f35dc14919a145b2d7a2d8842a43a18a629affe678233c4ea90b4af"},
+ {file = "safetensors-0.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcf527ecc5f58907fd9031510378105487f318cc91ecdc5aee3c7cc8f46030a8"},
+ {file = "safetensors-0.3.1-cp39-cp39-win32.whl", hash = "sha256:e2f083112cf97aa9611e2a05cc170a2795eccec5f6ff837f4565f950670a9d83"},
+ {file = "safetensors-0.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:5f4f614b8e8161cd8a9ca19c765d176a82b122fa3d3387b77862145bfe9b4e93"},
+ {file = "safetensors-0.3.1.tar.gz", hash = "sha256:571da56ff8d0bec8ae54923b621cda98d36dcef10feb36fd492c4d0c2cd0e869"},
+]
+
+[package.extras]
+all = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "flax (>=0.6.3)", "h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "isort (>=5.5.4)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "numpy (>=1.21.6)", "paddlepaddle (>=2.4.1)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "setuptools-rust (>=1.5.2)", "tensorflow (>=2.11.0)", "torch (>=1.10)"]
+dev = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "flax (>=0.6.3)", "h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "isort (>=5.5.4)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "numpy (>=1.21.6)", "paddlepaddle (>=2.4.1)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "setuptools-rust (>=1.5.2)", "tensorflow (>=2.11.0)", "torch (>=1.10)"]
+jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)"]
+numpy = ["numpy (>=1.21.6)"]
+paddlepaddle = ["paddlepaddle (>=2.4.1)"]
+quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"]
+tensorflow = ["tensorflow (>=2.11.0)"]
+testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "numpy (>=1.21.6)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "setuptools-rust (>=1.5.2)"]
+torch = ["torch (>=1.10)"]
+
+[[package]]
+name = "scikit-learn"
+version = "1.3.0"
+description = "A set of python modules for machine learning and data mining"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "scikit-learn-1.3.0.tar.gz", hash = "sha256:8be549886f5eda46436b6e555b0e4873b4f10aa21c07df45c4bc1735afbccd7a"},
+ {file = "scikit_learn-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:981287869e576d42c682cf7ca96af0c6ac544ed9316328fd0d9292795c742cf5"},
+ {file = "scikit_learn-1.3.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:436aaaae2c916ad16631142488e4c82f4296af2404f480e031d866863425d2a2"},
+ {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e28d8fa47a0b30ae1bd7a079519dd852764e31708a7804da6cb6f8b36e3630"},
+ {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80c08834a473d08a204d966982a62e11c976228d306a2648c575e3ead12111"},
+ {file = "scikit_learn-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:552fd1b6ee22900cf1780d7386a554bb96949e9a359999177cf30211e6b20df6"},
+ {file = "scikit_learn-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79970a6d759eb00a62266a31e2637d07d2d28446fca8079cf9afa7c07b0427f8"},
+ {file = "scikit_learn-1.3.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:850a00b559e636b23901aabbe79b73dc604b4e4248ba9e2d6e72f95063765603"},
+ {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee04835fb016e8062ee9fe9074aef9b82e430504e420bff51e3e5fffe72750ca"},
+ {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d953531f5d9f00c90c34fa3b7d7cfb43ecff4c605dac9e4255a20b114a27369"},
+ {file = "scikit_learn-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:151ac2bf65ccf363664a689b8beafc9e6aae36263db114b4ca06fbbbf827444a"},
+ {file = "scikit_learn-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a885a9edc9c0a341cab27ec4f8a6c58b35f3d449c9d2503a6fd23e06bbd4f6a"},
+ {file = "scikit_learn-1.3.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9877af9c6d1b15486e18a94101b742e9d0d2f343d35a634e337411ddb57783f3"},
+ {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c470f53cea065ff3d588050955c492793bb50c19a92923490d18fcb637f6383a"},
+ {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6e2d7389542eae01077a1ee0318c4fec20c66c957f45c7aac0c6eb0fe3c612"},
+ {file = "scikit_learn-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:3a11936adbc379a6061ea32fa03338d4ca7248d86dd507c81e13af428a5bc1db"},
+ {file = "scikit_learn-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:998d38fcec96584deee1e79cd127469b3ad6fefd1ea6c2dfc54e8db367eb396b"},
+ {file = "scikit_learn-1.3.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ded35e810438a527e17623ac6deae3b360134345b7c598175ab7741720d7ffa7"},
+ {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8102d5036e28d08ab47166b48c8d5e5810704daecf3a476a4282d562be9a28"},
+ {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7617164951c422747e7c32be4afa15d75ad8044f42e7d70d3e2e0429a50e6718"},
+ {file = "scikit_learn-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:1d54fb9e6038284548072df22fd34777e434153f7ffac72c8596f2d6987110dd"},
+]
+
+[package.dependencies]
+joblib = ">=1.1.1"
+numpy = ">=1.17.3"
+scipy = ">=1.5.0"
+threadpoolctl = ">=2.0.0"
+
+[package.extras]
+benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"]
+docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.10.1)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"]
+examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"]
+tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.16.2)"]
+
+[[package]]
+name = "scipy"
+version = "1.9.3"
+description = "Fundamental algorithms for scientific computing in Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"},
+ {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"},
+ {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"},
+ {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"},
+ {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"},
+ {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"},
+ {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"},
+ {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"},
+ {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"},
+ {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"},
+ {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"},
+ {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"},
+ {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"},
+ {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"},
+ {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"},
+ {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"},
+ {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"},
+ {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"},
+ {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"},
+ {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"},
+ {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"},
+]
+
+[package.dependencies]
+numpy = ">=1.18.5,<1.26.0"
+
+[package.extras]
+dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"]
+doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"]
+test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"]
+
+[[package]]
+name = "send2trash"
+version = "1.8.2"
+description = "Send file to trash natively under Mac OS X, Windows and Linux"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+files = [
+ {file = "Send2Trash-1.8.2-py3-none-any.whl", hash = "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679"},
+ {file = "Send2Trash-1.8.2.tar.gz", hash = "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312"},
+]
+
+[package.extras]
+nativelib = ["pyobjc-framework-Cocoa", "pywin32"]
+objc = ["pyobjc-framework-Cocoa"]
+win32 = ["pywin32"]
+
+[[package]]
+name = "sentence-transformers"
+version = "2.2.2"
+description = "Multilingual text embeddings"
+optional = false
+python-versions = ">=3.6.0"
+files = [
+ {file = "sentence-transformers-2.2.2.tar.gz", hash = "sha256:dbc60163b27de21076c9a30d24b5b7b6fa05141d68cf2553fa9a77bf79a29136"},
+]
+
+[package.dependencies]
+huggingface-hub = ">=0.4.0"
+nltk = "*"
+numpy = "*"
+scikit-learn = "*"
+scipy = "*"
+sentencepiece = "*"
+torch = ">=1.6.0"
+torchvision = "*"
+tqdm = "*"
+transformers = ">=4.6.0,<5.0.0"
+
+[[package]]
+name = "sentencepiece"
+version = "0.1.99"
+description = "SentencePiece python wrapper"
+optional = false
+python-versions = "*"
+files = [
+ {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0eb528e70571b7c02723e5804322469b82fe7ea418c96051d0286c0fa028db73"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77d7fafb2c4e4659cbdf303929503f37a26eabc4ff31d3a79bf1c5a1b338caa7"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be9cf5b9e404c245aeb3d3723c737ba7a8f5d4ba262ef233a431fa6c45f732a0"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baed1a26464998f9710d20e52607c29ffd4293e7c71c6a1f83f51ad0911ec12c"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9832f08bb372d4c8b567612f8eab9e36e268dff645f1c28f9f8e851be705f6d1"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:019e7535108e309dae2b253a75834fc3128240aa87c00eb80732078cdc182588"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-win32.whl", hash = "sha256:fa16a830416bb823fa2a52cbdd474d1f7f3bba527fd2304fb4b140dad31bb9bc"},
+ {file = "sentencepiece-0.1.99-cp310-cp310-win_amd64.whl", hash = "sha256:14b0eccb7b641d4591c3e12ae44cab537d68352e4d3b6424944f0c447d2348d5"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6d3c56f24183a1e8bd61043ff2c58dfecdc68a5dd8955dc13bab83afd5f76b81"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed6ea1819fd612c989999e44a51bf556d0ef6abfb553080b9be3d347e18bcfb7"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2a0260cd1fb7bd8b4d4f39dc2444a8d5fd4e0a0c4d5c899810ef1abf99b2d45"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a1abff4d1ff81c77cac3cc6fefa34fa4b8b371e5ee51cb7e8d1ebc996d05983"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:004e6a621d4bc88978eecb6ea7959264239a17b70f2cbc348033d8195c9808ec"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db361e03342c41680afae5807590bc88aa0e17cfd1a42696a160e4005fcda03b"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-win32.whl", hash = "sha256:2d95e19168875b70df62916eb55428a0cbcb834ac51d5a7e664eda74def9e1e0"},
+ {file = "sentencepiece-0.1.99-cp311-cp311-win_amd64.whl", hash = "sha256:f90d73a6f81248a909f55d8e6ef56fec32d559e1e9af045f0b0322637cb8e5c7"},
+ {file = "sentencepiece-0.1.99-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:62e24c81e74bd87a6e0d63c51beb6527e4c0add67e1a17bac18bcd2076afcfeb"},
+ {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57efcc2d51caff20d9573567d9fd3f854d9efe613ed58a439c78c9f93101384a"},
+ {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a904c46197993bd1e95b93a6e373dca2f170379d64441041e2e628ad4afb16f"},
+ {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89adf59854741c0d465f0e1525b388c0d174f611cc04af54153c5c4f36088c4"},
+ {file = "sentencepiece-0.1.99-cp36-cp36m-win32.whl", hash = "sha256:47c378146928690d1bc106fdf0da768cebd03b65dd8405aa3dd88f9c81e35dba"},
+ {file = "sentencepiece-0.1.99-cp36-cp36m-win_amd64.whl", hash = "sha256:9ba142e7a90dd6d823c44f9870abdad45e6c63958eb60fe44cca6828d3b69da2"},
+ {file = "sentencepiece-0.1.99-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b7b1a9ae4d7c6f1f867e63370cca25cc17b6f4886729595b885ee07a58d3cec3"},
+ {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0f644c9d4d35c096a538507b2163e6191512460035bf51358794a78515b74f7"},
+ {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8843d23a0f686d85e569bd6dcd0dd0e0cbc03731e63497ca6d5bacd18df8b85"},
+ {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33e6f690a1caebb4867a2e367afa1918ad35be257ecdb3455d2bbd787936f155"},
+ {file = "sentencepiece-0.1.99-cp37-cp37m-win32.whl", hash = "sha256:8a321866c2f85da7beac74a824b4ad6ddc2a4c9bccd9382529506d48f744a12c"},
+ {file = "sentencepiece-0.1.99-cp37-cp37m-win_amd64.whl", hash = "sha256:c42f753bcfb7661c122a15b20be7f684b61fc8592c89c870adf52382ea72262d"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b476406da69c70586f0bb682fcca4c9b40e5059814f2db92303ea4585c650c"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfbcfe13c69d3f87b7fcd5da168df7290a6d006329be71f90ba4f56bc77f8561"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:445b0ec381af1cd4eef95243e7180c63d9c384443c16c4c47a28196bd1cda937"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6890ea0f2b4703f62d0bf27932e35808b1f679bdb05c7eeb3812b935ba02001"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb71af492b0eefbf9f2501bec97bcd043b6812ab000d119eaf4bd33f9e283d03"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27b866b5bd3ddd54166bbcbf5c8d7dd2e0b397fac8537991c7f544220b1f67bc"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-win32.whl", hash = "sha256:b133e8a499eac49c581c3c76e9bdd08c338cc1939e441fee6f92c0ccb5f1f8be"},
+ {file = "sentencepiece-0.1.99-cp38-cp38-win_amd64.whl", hash = "sha256:0eaf3591dd0690a87f44f4df129cf8d05d8a4029b5b6709b489b8e27f9a9bcff"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38efeda9bbfb55052d482a009c6a37e52f42ebffcea9d3a98a61de7aee356a28"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6c030b081dc1e1bcc9fadc314b19b740715d3d566ad73a482da20d7d46fd444c"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84dbe53e02e4f8a2e45d2ac3e430d5c83182142658e25edd76539b7648928727"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b0f55d0a0ee1719b4b04221fe0c9f0c3461dc3dabd77a035fa2f4788eb3ef9a"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e800f206cd235dc27dc749299e05853a4e4332e8d3dfd81bf13d0e5b9007d9"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae1c40cda8f9d5b0423cfa98542735c0235e7597d79caf318855cdf971b2280"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-win32.whl", hash = "sha256:c84ce33af12ca222d14a1cdd37bd76a69401e32bc68fe61c67ef6b59402f4ab8"},
+ {file = "sentencepiece-0.1.99-cp39-cp39-win_amd64.whl", hash = "sha256:350e5c74d739973f1c9643edb80f7cc904dc948578bcb1d43c6f2b173e5d18dd"},
+ {file = "sentencepiece-0.1.99.tar.gz", hash = "sha256:189c48f5cb2949288f97ccdb97f0473098d9c3dcf5a3d99d4eabe719ec27297f"},
+]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "sniffio"
+version = "1.3.0"
+description = "Sniff out which async library your code is running under"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
+ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
+]
+
+[[package]]
+name = "soupsieve"
+version = "2.4.1"
+description = "A modern CSS selector implementation for Beautiful Soup."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"},
+ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"},
+]
+
+[[package]]
+name = "stack-data"
+version = "0.6.2"
+description = "Extract data from python stack frames and tracebacks for informative displays"
+optional = false
+python-versions = "*"
+files = [
+ {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"},
+ {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"},
+]
+
+[package.dependencies]
+asttokens = ">=2.1.0"
+executing = ">=1.2.0"
+pure-eval = "*"
+
+[package.extras]
+tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
+
+[[package]]
+name = "sympy"
+version = "1.12"
+description = "Computer algebra system (CAS) in Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"},
+ {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"},
+]
+
+[package.dependencies]
+mpmath = ">=0.19"
+
+[[package]]
+name = "terminado"
+version = "0.17.1"
+description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"},
+ {file = "terminado-0.17.1.tar.gz", hash = "sha256:6ccbbcd3a4f8a25a5ec04991f39a0b8db52dfcd487ea0e578d977e6752380333"},
+]
+
+[package.dependencies]
+ptyprocess = {version = "*", markers = "os_name != \"nt\""}
+pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""}
+tornado = ">=6.1.0"
+
+[package.extras]
+docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"]
+test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"]
+
+[[package]]
+name = "threadpoolctl"
+version = "3.2.0"
+description = "threadpoolctl"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032"},
+ {file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355"},
+]
+
+[[package]]
+name = "timm"
+version = "0.9.2"
+description = "PyTorch Image Models"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "timm-0.9.2-py3-none-any.whl", hash = "sha256:8da40cc58ed32b0622bf87d8714f9b7023398ba4cfa8fa678578d2aefde4a909"},
+ {file = "timm-0.9.2.tar.gz", hash = "sha256:d0977cc5e02c69bda979fca8b52aa315a5f2cb64ebf8ad2c4631b1e452762c14"},
+]
+
+[package.dependencies]
+huggingface-hub = "*"
+pyyaml = "*"
+safetensors = "*"
+torch = ">=1.7"
+torchvision = "*"
+
+[[package]]
+name = "tinycss2"
+version = "1.2.1"
+description = "A tiny CSS parser"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"},
+ {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"},
+]
+
+[package.dependencies]
+webencodings = ">=0.4"
+
+[package.extras]
+doc = ["sphinx", "sphinx_rtd_theme"]
+test = ["flake8", "isort", "pytest"]
+
+[[package]]
+name = "tokenizers"
+version = "0.13.3"
+description = "Fast and Customizable Tokenizers"
+optional = false
+python-versions = "*"
+files = [
+ {file = "tokenizers-0.13.3-cp310-cp310-macosx_10_11_x86_64.whl", hash = "sha256:f3835c5be51de8c0a092058a4d4380cb9244fb34681fd0a295fbf0a52a5fdf33"},
+ {file = "tokenizers-0.13.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4ef4c3e821730f2692489e926b184321e887f34fb8a6b80b8096b966ba663d07"},
+ {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5fd1a6a25353e9aa762e2aae5a1e63883cad9f4e997c447ec39d071020459bc"},
+ {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee0b1b311d65beab83d7a41c56a1e46ab732a9eed4460648e8eb0bd69fc2d059"},
+ {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ef4215284df1277dadbcc5e17d4882bda19f770d02348e73523f7e7d8b8d396"},
+ {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4d53976079cff8a033f778fb9adca2d9d69d009c02fa2d71a878b5f3963ed30"},
+ {file = "tokenizers-0.13.3-cp310-cp310-win32.whl", hash = "sha256:1f0e3b4c2ea2cd13238ce43548959c118069db7579e5d40ec270ad77da5833ce"},
+ {file = "tokenizers-0.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:89649c00d0d7211e8186f7a75dfa1db6996f65edce4b84821817eadcc2d3c79e"},
+ {file = "tokenizers-0.13.3-cp311-cp311-macosx_10_11_universal2.whl", hash = "sha256:56b726e0d2bbc9243872b0144515ba684af5b8d8cd112fb83ee1365e26ec74c8"},
+ {file = "tokenizers-0.13.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:cc5c022ce692e1f499d745af293ab9ee6f5d92538ed2faf73f9708c89ee59ce6"},
+ {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f55c981ac44ba87c93e847c333e58c12abcbb377a0c2f2ef96e1a266e4184ff2"},
+ {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f247eae99800ef821a91f47c5280e9e9afaeed9980fc444208d5aa6ba69ff148"},
+ {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b3e3215d048e94f40f1c95802e45dcc37c5b05eb46280fc2ccc8cd351bff839"},
+ {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ba2b0bf01777c9b9bc94b53764d6684554ce98551fec496f71bc5be3a03e98b"},
+ {file = "tokenizers-0.13.3-cp311-cp311-win32.whl", hash = "sha256:cc78d77f597d1c458bf0ea7c2a64b6aa06941c7a99cb135b5969b0278824d808"},
+ {file = "tokenizers-0.13.3-cp311-cp311-win_amd64.whl", hash = "sha256:ecf182bf59bd541a8876deccf0360f5ae60496fd50b58510048020751cf1724c"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:0527dc5436a1f6bf2c0327da3145687d3bcfbeab91fed8458920093de3901b44"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07cbb2c307627dc99b44b22ef05ff4473aa7c7cc1fec8f0a8b37d8a64b1a16d2"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4560dbdeaae5b7ee0d4e493027e3de6d53c991b5002d7ff95083c99e11dd5ac0"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64064bd0322405c9374305ab9b4c07152a1474370327499911937fd4a76d004b"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8c6e2ab0f2e3d939ca66aa1d596602105fe33b505cd2854a4c1717f704c51de"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-win32.whl", hash = "sha256:6cc29d410768f960db8677221e497226e545eaaea01aa3613fa0fdf2cc96cff4"},
+ {file = "tokenizers-0.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fc2a7fdf864554a0dacf09d32e17c0caa9afe72baf9dd7ddedc61973bae352d8"},
+ {file = "tokenizers-0.13.3-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:8791dedba834c1fc55e5f1521be325ea3dafb381964be20684b92fdac95d79b7"},
+ {file = "tokenizers-0.13.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:d607a6a13718aeb20507bdf2b96162ead5145bbbfa26788d6b833f98b31b26e1"},
+ {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3791338f809cd1bf8e4fee6b540b36822434d0c6c6bc47162448deee3f77d425"},
+ {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2f35f30e39e6aab8716f07790f646bdc6e4a853816cc49a95ef2a9016bf9ce6"},
+ {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310204dfed5aa797128b65d63538a9837cbdd15da2a29a77d67eefa489edda26"},
+ {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0f9b92ea052305166559f38498b3b0cae159caea712646648aaa272f7160963"},
+ {file = "tokenizers-0.13.3-cp38-cp38-win32.whl", hash = "sha256:9a3fa134896c3c1f0da6e762d15141fbff30d094067c8f1157b9fdca593b5806"},
+ {file = "tokenizers-0.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:8e7b0cdeace87fa9e760e6a605e0ae8fc14b7d72e9fc19c578116f7287bb873d"},
+ {file = "tokenizers-0.13.3-cp39-cp39-macosx_10_11_x86_64.whl", hash = "sha256:00cee1e0859d55507e693a48fa4aef07060c4bb6bd93d80120e18fea9371c66d"},
+ {file = "tokenizers-0.13.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a23ff602d0797cea1d0506ce69b27523b07e70f6dda982ab8cf82402de839088"},
+ {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ce07445050b537d2696022dafb115307abdffd2a5c106f029490f84501ef97"},
+ {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:280ffe95f50eaaf655b3a1dc7ff1d9cf4777029dbbc3e63a74e65a056594abc3"},
+ {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97acfcec592f7e9de8cadcdcda50a7134423ac8455c0166b28c9ff04d227b371"},
+ {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd7730c98a3010cd4f523465867ff95cd9d6430db46676ce79358f65ae39797b"},
+ {file = "tokenizers-0.13.3-cp39-cp39-win32.whl", hash = "sha256:48625a108029cb1ddf42e17a81b5a3230ba6888a70c9dc14e81bc319e812652d"},
+ {file = "tokenizers-0.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:bc0a6f1ba036e482db6453571c9e3e60ecd5489980ffd95d11dc9f960483d783"},
+ {file = "tokenizers-0.13.3.tar.gz", hash = "sha256:2e546dbb68b623008a5442353137fbb0123d311a6d7ba52f2667c8862a75af2e"},
+]
+
+[package.extras]
+dev = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"]
+docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"]
+testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"]
+
+[[package]]
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
+
+[[package]]
+name = "torch"
+version = "2.0.1"
+description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration"
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "torch-2.0.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:8ced00b3ba471856b993822508f77c98f48a458623596a4c43136158781e306a"},
+ {file = "torch-2.0.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:359bfaad94d1cda02ab775dc1cc386d585712329bb47b8741607ef6ef4950747"},
+ {file = "torch-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:7c84e44d9002182edd859f3400deaa7410f5ec948a519cc7ef512c2f9b34d2c4"},
+ {file = "torch-2.0.1-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:567f84d657edc5582d716900543e6e62353dbe275e61cdc36eda4929e46df9e7"},
+ {file = "torch-2.0.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:787b5a78aa7917465e9b96399b883920c88a08f4eb63b5a5d2d1a16e27d2f89b"},
+ {file = "torch-2.0.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:e617b1d0abaf6ced02dbb9486803abfef0d581609b09641b34fa315c9c40766d"},
+ {file = "torch-2.0.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b6019b1de4978e96daa21d6a3ebb41e88a0b474898fe251fd96189587408873e"},
+ {file = "torch-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:dbd68cbd1cd9da32fe5d294dd3411509b3d841baecb780b38b3b7b06c7754434"},
+ {file = "torch-2.0.1-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:ef654427d91600129864644e35deea761fb1fe131710180b952a6f2e2207075e"},
+ {file = "torch-2.0.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:25aa43ca80dcdf32f13da04c503ec7afdf8e77e3a0183dd85cd3e53b2842e527"},
+ {file = "torch-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5ef3ea3d25441d3957348f7e99c7824d33798258a2bf5f0f0277cbcadad2e20d"},
+ {file = "torch-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0882243755ff28895e8e6dc6bc26ebcf5aa0911ed81b2a12f241fc4b09075b13"},
+ {file = "torch-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:f66aa6b9580a22b04d0af54fcd042f52406a8479e2b6a550e3d9f95963e168c8"},
+ {file = "torch-2.0.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:1adb60d369f2650cac8e9a95b1d5758e25d526a34808f7448d0bd599e4ae9072"},
+ {file = "torch-2.0.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:1bcffc16b89e296826b33b98db5166f990e3b72654a2b90673e817b16c50e32b"},
+ {file = "torch-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:e10e1597f2175365285db1b24019eb6f04d53dcd626c735fc502f1e8b6be9875"},
+ {file = "torch-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:423e0ae257b756bb45a4b49072046772d1ad0c592265c5080070e0767da4e490"},
+ {file = "torch-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8742bdc62946c93f75ff92da00e3803216c6cce9b132fbca69664ca38cfb3e18"},
+ {file = "torch-2.0.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:c62df99352bd6ee5a5a8d1832452110435d178b5164de450831a3a8cc14dc680"},
+ {file = "torch-2.0.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:671a2565e3f63b8fe8e42ae3e36ad249fe5e567435ea27b94edaa672a7d0c416"},
+]
+
+[package.dependencies]
+filelock = "*"
+jinja2 = "*"
+networkx = "*"
+sympy = "*"
+typing-extensions = "*"
+
+[package.extras]
+opt-einsum = ["opt-einsum (>=3.3)"]
+
+[[package]]
+name = "torchvision"
+version = "0.15.2"
+description = "image and video datasets and models for torch deep learning"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "torchvision-0.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7754088774e810c5672b142a45dcf20b1bd986a5a7da90f8660c43dc43fb850c"},
+ {file = "torchvision-0.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37eb138e13f6212537a3009ac218695483a635c404b6cc1d8e0d0d978026a86d"},
+ {file = "torchvision-0.15.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:54143f7cc0797d199b98a53b7d21c3f97615762d4dd17ad45a41c7e80d880e73"},
+ {file = "torchvision-0.15.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:1eefebf5fbd01a95fe8f003d623d941601c94b5cec547b420da89cb369d9cf96"},
+ {file = "torchvision-0.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:96fae30c5ca8423f4b9790df0f0d929748e32718d88709b7b567d2f630c042e3"},
+ {file = "torchvision-0.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5f35f6bd5bcc4568e6522e4137fa60fcc72f4fa3e615321c26cd87e855acd398"},
+ {file = "torchvision-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:757505a0ab2be7096cb9d2bf4723202c971cceddb72c7952a7e877f773de0f8a"},
+ {file = "torchvision-0.15.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:012ad25cfd9019ff9b0714a168727e3845029be1af82296ff1e1482931fa4b80"},
+ {file = "torchvision-0.15.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b02a7ffeaa61448737f39a4210b8ee60234bda0515a0c0d8562f884454105b0f"},
+ {file = "torchvision-0.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:10be76ceded48329d0a0355ac33da131ee3993ff6c125e4a02ab34b5baa2472c"},
+ {file = "torchvision-0.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f12415b686dba884fb086f53ac803f692be5a5cdd8a758f50812b30fffea2e4"},
+ {file = "torchvision-0.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:31211c01f8b8ec33b8a638327b5463212e79a03e43c895f88049f97af1bd12fd"},
+ {file = "torchvision-0.15.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c55f9889e436f14b4f84a9c00ebad0d31f5b4626f10cf8018e6c676f92a6d199"},
+ {file = "torchvision-0.15.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:9a192f2aa979438f23c20e883980b23d13268ab9f819498774a6d2eb021802c2"},
+ {file = "torchvision-0.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:c07071bc8d02aa8fcdfe139ab6a1ef57d3b64c9e30e84d12d45c9f4d89fb6536"},
+ {file = "torchvision-0.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4790260fcf478a41c7ecc60a6d5200a88159fdd8d756e9f29f0f8c59c4a67a68"},
+ {file = "torchvision-0.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:987ab62225b4151a11e53fd06150c5258ced24ac9d7c547e0e4ab6fbca92a5ce"},
+ {file = "torchvision-0.15.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:63df26673e66cba3f17e07c327a8cafa3cce98265dbc3da329f1951d45966838"},
+ {file = "torchvision-0.15.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b85f98d4cc2f72452f6792ab4463a3541bc5678a8cdd3da0e139ba2fe8b56d42"},
+ {file = "torchvision-0.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:07c462524cc1bba5190c16a9d47eac1fca024d60595a310f23c00b4ffff18b30"},
+]
+
+[package.dependencies]
+numpy = "*"
+pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0"
+requests = "*"
+torch = "2.0.1"
+
+[package.extras]
+scipy = ["scipy"]
+
+[[package]]
+name = "tornado"
+version = "6.3.2"
+description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
+optional = false
+python-versions = ">= 3.8"
+files = [
+ {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"},
+ {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"},
+ {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"},
+ {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"},
+ {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"},
+ {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"},
+ {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"},
+ {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"},
+ {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"},
+ {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"},
+ {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"},
+]
+
+[[package]]
+name = "tqdm"
+version = "4.65.0"
+description = "Fast, Extensible Progress Meter"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"},
+ {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
+
+[package.extras]
+dev = ["py-make (>=0.1.0)", "twine", "wheel"]
+notebook = ["ipywidgets (>=6)"]
+slack = ["slack-sdk"]
+telegram = ["requests"]
+
+[[package]]
+name = "traitlets"
+version = "5.9.0"
+description = "Traitlets Python configuration system"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"},
+ {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"},
+]
+
+[package.extras]
+docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"]
+test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"]
+
+[[package]]
+name = "transformers"
+version = "4.31.0"
+description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow"
+optional = false
+python-versions = ">=3.8.0"
+files = [
+ {file = "transformers-4.31.0-py3-none-any.whl", hash = "sha256:8487aab0195ce1c2a5ae189305118b9720daddbc7b688edb09ccd79e3b149f6b"},
+ {file = "transformers-4.31.0.tar.gz", hash = "sha256:4302fba920a1c24d3a429a29efff6a63eac03f3f3cf55b55927fc795d01cb273"},
+]
+
+[package.dependencies]
+filelock = "*"
+huggingface-hub = ">=0.14.1,<1.0"
+numpy = ">=1.17"
+packaging = ">=20.0"
+protobuf = {version = "*", optional = true, markers = "extra == \"sentencepiece\""}
+pyyaml = ">=5.1"
+regex = "!=2019.12.17"
+requests = "*"
+safetensors = ">=0.3.1"
+sentencepiece = {version = ">=0.1.91,<0.1.92 || >0.1.92", optional = true, markers = "extra == \"sentencepiece\""}
+tokenizers = ">=0.11.1,<0.11.3 || >0.11.3,<0.14"
+tqdm = ">=4.27"
+
+[package.extras]
+accelerate = ["accelerate (>=0.20.3)"]
+agents = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.9,!=1.12.0)"]
+all = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"]
+audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
+codecarbon = ["codecarbon (==1.2.0)"]
+deepspeed = ["accelerate (>=0.20.3)", "deepspeed (>=0.9.3)"]
+deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "timeout-decorator"]
+dev = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
+dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "urllib3 (<2.0.0)"]
+dev-torch = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"]
+docs = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"]
+docs-specific = ["hf-doc-builder"]
+fairscale = ["fairscale (>0.3)"]
+flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"]
+flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
+ftfy = ["ftfy"]
+integrations = ["optuna", "ray[tune]", "sigopt"]
+ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0,<1.3.1)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"]
+modelcreation = ["cookiecutter (==1.7.3)"]
+natten = ["natten (>=0.14.6)"]
+onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"]
+onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"]
+optuna = ["optuna"]
+quality = ["GitPython (<3.1.19)", "black (>=23.1,<24.0)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (>=0.0.241,<=0.0.259)", "urllib3 (<2.0.0)"]
+ray = ["ray[tune]"]
+retrieval = ["datasets (!=2.5.0)", "faiss-cpu"]
+sagemaker = ["sagemaker (>=2.31.0)"]
+sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"]
+serving = ["fastapi", "pydantic (<2)", "starlette", "uvicorn"]
+sigopt = ["sigopt"]
+sklearn = ["scikit-learn"]
+speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"]
+testing = ["GitPython (<3.1.19)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "timeout-decorator"]
+tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx"]
+tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx"]
+tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"]
+timm = ["timm"]
+tokenizers = ["tokenizers (>=0.11.1,!=0.11.3,<0.14)"]
+torch = ["accelerate (>=0.20.3)", "torch (>=1.9,!=1.12.0)"]
+torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"]
+torch-vision = ["Pillow (<10.0.0)", "torchvision"]
+torchhub = ["filelock", "huggingface-hub (>=0.14.1,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "tqdm (>=4.27)"]
+video = ["av (==9.2.0)", "decord (==0.6.0)"]
+vision = ["Pillow (<10.0.0)"]
+
+[[package]]
+name = "typing-extensions"
+version = "4.7.1"
+description = "Backported and Experimental Type Hints for Python 3.7+"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
+ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
+]
+
+[[package]]
+name = "tzdata"
+version = "2023.3"
+description = "Provider of IANA time zone data"
+optional = false
+python-versions = ">=2"
+files = [
+ {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"},
+ {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"},
+]
+
+[[package]]
+name = "uri-template"
+version = "1.3.0"
+description = "RFC 6570 URI Template Processor"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"},
+ {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"},
+]
+
+[package.extras]
+dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"]
+
+[[package]]
+name = "urllib3"
+version = "2.0.4"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"},
+ {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"},
+]
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
+socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
+zstd = ["zstandard (>=0.18.0)"]
+
+[[package]]
+name = "wcwidth"
+version = "0.2.6"
+description = "Measures the displayed width of unicode strings in a terminal"
+optional = false
+python-versions = "*"
+files = [
+ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"},
+ {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"},
+]
+
+[[package]]
+name = "webcolors"
+version = "1.13"
+description = "A library for working with the color formats defined by HTML and CSS."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"},
+ {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"},
+]
+
+[package.extras]
+docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"]
+tests = ["pytest", "pytest-cov"]
+
+[[package]]
+name = "webencodings"
+version = "0.5.1"
+description = "Character encoding aliases for legacy web content"
+optional = false
+python-versions = "*"
+files = [
+ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
+ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
+]
+
+[[package]]
+name = "websocket-client"
+version = "1.6.1"
+description = "WebSocket client for Python with low level API options"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"},
+ {file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"},
+]
+
+[package.extras]
+docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"]
+optional = ["python-socks", "wsaccel"]
+test = ["websockets"]
+
+[[package]]
+name = "widgetsnbextension"
+version = "4.0.8"
+description = "Jupyter interactive widgets for Jupyter Notebook"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "widgetsnbextension-4.0.8-py3-none-any.whl", hash = "sha256:2e37f0ce9da11651056280c7efe96f2db052fe8fc269508e3724f5cbd6c93018"},
+ {file = "widgetsnbextension-4.0.8.tar.gz", hash = "sha256:9ec291ba87c2dfad42c3d5b6f68713fa18be1acd7476569516b2431682315c17"},
+]
+
+[[package]]
+name = "xxhash"
+version = "3.2.0"
+description = "Python binding for xxHash"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "xxhash-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:af44b9e59c4b2926a4e3c7f9d29949ff42fcea28637ff6b8182e654461932be8"},
+ {file = "xxhash-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1bdd57973e2b802ef32553d7bebf9402dac1557874dbe5c908b499ea917662cd"},
+ {file = "xxhash-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b7c9aa77bbce61a5e681bd39cb6a804338474dcc90abe3c543592aa5d6c9a9b"},
+ {file = "xxhash-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11bf87dc7bb8c3b0b5e24b7b941a9a19d8c1f88120b6a03a17264086bc8bb023"},
+ {file = "xxhash-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2783d41487ce6d379fdfaa7332fca5187bf7010b9bddcf20cafba923bc1dc665"},
+ {file = "xxhash-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:561076ca0dcef2fbc20b2bc2765bff099e002e96041ae9dbe910a863ca6ee3ea"},
+ {file = "xxhash-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a26eeb4625a6e61cedc8c1b39b89327c9c7e1a8c2c4d786fe3f178eb839ede6"},
+ {file = "xxhash-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d93a44d0104d1b9b10de4e7aadf747f6efc1d7ec5ed0aa3f233a720725dd31bd"},
+ {file = "xxhash-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:89585adc73395a10306d2e2036e50d6c4ac0cf8dd47edf914c25488871b64f6d"},
+ {file = "xxhash-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a892b4b139126a86bfdcb97cd912a2f8c4e8623869c3ef7b50871451dd7afeb0"},
+ {file = "xxhash-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e998efb190653f70e0f30d92b39fc645145369a4823bee46af8ddfc244aa969d"},
+ {file = "xxhash-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e8ed3bd2b8bb3277710843ca63e4f5c3ee6f8f80b083be5b19a7a9905420d11e"},
+ {file = "xxhash-3.2.0-cp310-cp310-win32.whl", hash = "sha256:20181cbaed033c72cb881b2a1d13c629cd1228f113046133469c9a48cfcbcd36"},
+ {file = "xxhash-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:a0f7a16138279d707db778a63264d1d6016ac13ffd3f1e99f54b2855d6c0d8e1"},
+ {file = "xxhash-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5daff3fb5bfef30bc5a2cb143810d376d43461445aa17aece7210de52adbe151"},
+ {file = "xxhash-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75bb5be3c5de702a547715f320ecf5c8014aeca750ed5147ca75389bd22e7343"},
+ {file = "xxhash-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01f36b671ff55cb1d5c2f6058b799b697fd0ae4b4582bba6ed0999678068172a"},
+ {file = "xxhash-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4d4519123aac73c93159eb8f61db9682393862dd669e7eae034ecd0a35eadac"},
+ {file = "xxhash-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:994e4741d5ed70fc2a335a91ef79343c6b1089d7dfe6e955dd06f8ffe82bede6"},
+ {file = "xxhash-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919bc1b010aa6ff0eb918838ff73a435aed9e9a19c3202b91acecd296bf75607"},
+ {file = "xxhash-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17b65454c5accbb079c45eca546c27c4782f5175aa320758fafac896b1549d27"},
+ {file = "xxhash-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b0c094d5e65a46dbf3fe0928ff20873a747e6abfd2ed4b675beeb2750624bc2e"},
+ {file = "xxhash-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f94163ebe2d5546e6a5977e96d83621f4689c1054053428cf8d4c28b10f92f69"},
+ {file = "xxhash-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cead7c0307977a00b3f784cff676e72c147adbcada19a2e6fc2ddf54f37cf387"},
+ {file = "xxhash-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:a0e1bd0260c1da35c1883321ce2707ceea07127816ab625e1226ec95177b561a"},
+ {file = "xxhash-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc8878935671490efe9275fb4190a6062b73277bd273237179b9b5a2aa436153"},
+ {file = "xxhash-3.2.0-cp311-cp311-win32.whl", hash = "sha256:a433f6162b18d52f7068175d00bd5b1563b7405f926a48d888a97b90a160c40d"},
+ {file = "xxhash-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:a32d546a1752e4ee7805d6db57944f7224afa7428d22867006b6486e4195c1f3"},
+ {file = "xxhash-3.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:82daaab720866bf690b20b49de5640b0c27e3b8eea2d08aa75bdca2b0f0cfb63"},
+ {file = "xxhash-3.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3126df6520cbdbaddd87ce74794b2b6c45dd2cf6ac2b600a374b8cdb76a2548c"},
+ {file = "xxhash-3.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e172c1ee40507ae3b8d220f4048aaca204f203e1e4197e8e652f5c814f61d1aa"},
+ {file = "xxhash-3.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5384f1d9f30876f5d5b618464fb19ff7ce6c0fe4c690fbaafd1c52adc3aae807"},
+ {file = "xxhash-3.2.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26cb52174a7e96a17acad27a3ca65b24713610ac479c99ac9640843822d3bebf"},
+ {file = "xxhash-3.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbcd613a5e76b1495fc24db9c37a6b7ee5f214fd85979187ec4e032abfc12ded"},
+ {file = "xxhash-3.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f988daf25f31726d5b9d0be6af636ca9000898f9ea43a57eac594daea25b0948"},
+ {file = "xxhash-3.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bbc30c98ab006ab9fc47e5ed439c00f706bc9d4441ff52693b8b6fea335163e0"},
+ {file = "xxhash-3.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:2408d49260b0a4a7cc6ba445aebf38e073aeaf482f8e32767ca477e32ccbbf9e"},
+ {file = "xxhash-3.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:3f4152fd0bf8b03b79f2f900fd6087a66866537e94b5a11fd0fd99ef7efe5c42"},
+ {file = "xxhash-3.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0eea848758e4823a01abdbcccb021a03c1ee4100411cbeeb7a5c36a202a0c13c"},
+ {file = "xxhash-3.2.0-cp36-cp36m-win32.whl", hash = "sha256:77709139af5123c578ab06cf999429cdb9ab211047acd0c787e098dcb3f1cb4d"},
+ {file = "xxhash-3.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:91687671fd9d484a4e201ad266d366b695a45a1f2b41be93d116ba60f1b8f3b3"},
+ {file = "xxhash-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e4af8bc5c3fcc2192c266421c6aa2daab1a18e002cb8e66ef672030e46ae25cf"},
+ {file = "xxhash-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8be562e2ce3e481d9209b6f254c3d7c5ff920eb256aba2380d2fb5ba75d4f87"},
+ {file = "xxhash-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9eba0c7c12126b12f7fcbea5513f28c950d28f33d2a227f74b50b77789e478e8"},
+ {file = "xxhash-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2198c4901a0223c48f6ec0a978b60bca4f4f7229a11ca4dc96ca325dd6a29115"},
+ {file = "xxhash-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50ce82a71b22a3069c02e914bf842118a53065e2ec1c6fb54786e03608ab89cc"},
+ {file = "xxhash-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5019fb33711c30e54e4e57ae0ca70af9d35b589d385ac04acd6954452fa73bb"},
+ {file = "xxhash-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d54ac023eef7e3ac9f0b8841ae8a376b933043bc2ad428121346c6fa61c491c"},
+ {file = "xxhash-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c55fa832fc3fe64e0d29da5dc9b50ba66ca93312107cec2709300ea3d3bab5c7"},
+ {file = "xxhash-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4ce006215497993ae77c612c1883ca4f3973899573ce0c52fee91f0d39c4561"},
+ {file = "xxhash-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:1afb9b9d27fd675b436cb110c15979976d92d761ad6e66799b83756402f3a974"},
+ {file = "xxhash-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:baa99cebf95c1885db21e119395f222a706a2bb75a545f0672880a442137725e"},
+ {file = "xxhash-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:75aa692936942ccb2e8fd6a386c81c61630ac1b6d6e921698122db8a930579c3"},
+ {file = "xxhash-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:0a2cdfb5cae9fafb9f7b65fd52ecd60cf7d72c13bb2591ea59aaefa03d5a8827"},
+ {file = "xxhash-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a68d1e8a390b660d94b9360ae5baa8c21a101bd9c4790a8b30781bada9f1fc6"},
+ {file = "xxhash-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ce7c3ce28f94302df95eaea7c9c1e2c974b6d15d78a0c82142a97939d7b6c082"},
+ {file = "xxhash-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0dcb419bf7b0bc77d366e5005c25682249c5521a63fd36c51f584bd91bb13bd5"},
+ {file = "xxhash-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae521ed9287f86aac979eeac43af762f03d9d9797b2272185fb9ddd810391216"},
+ {file = "xxhash-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0d16775094423088ffa357d09fbbb9ab48d2fb721d42c0856b801c86f616eec"},
+ {file = "xxhash-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe454aeab348c42f56d6f7434ff758a3ef90787ac81b9ad5a363cd61b90a1b0b"},
+ {file = "xxhash-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052fd0efdd5525c2dbc61bebb423d92aa619c4905bba605afbf1e985a562a231"},
+ {file = "xxhash-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:02badf3754e2133de254a4688798c4d80f0060635087abcb461415cb3eb82115"},
+ {file = "xxhash-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:66b8a90b28c13c2aae7a71b32638ceb14cefc2a1c8cf23d8d50dfb64dfac7aaf"},
+ {file = "xxhash-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:649cdf19df175925ad87289ead6f760cd840730ee85abc5eb43be326a0a24d97"},
+ {file = "xxhash-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4b948a03f89f5c72d69d40975af8af241111f0643228796558dc1cae8f5560b0"},
+ {file = "xxhash-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49f51fab7b762da7c2cee0a3d575184d3b9be5e2f64f26cae2dd286258ac9b3c"},
+ {file = "xxhash-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1a42994f0d42b55514785356722d9031f064fd34e495b3a589e96db68ee0179d"},
+ {file = "xxhash-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0a6d58ba5865475e53d6c2c4fa6a62e2721e7875e146e2681e5337a6948f12e7"},
+ {file = "xxhash-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aabdbc082030f8df613e2d2ea1f974e7ad36a539bdfc40d36f34e55c7e4b8e94"},
+ {file = "xxhash-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:498843b66b9ca416e9d03037e5875c8d0c0ab9037527e22df3b39aa5163214cd"},
+ {file = "xxhash-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a910b1193cd90af17228f5d6069816646df0148f14f53eefa6b2b11a1dedfcd0"},
+ {file = "xxhash-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb6d8ce31dc25faf4da92991320e211fa7f42de010ef51937b1dc565a4926501"},
+ {file = "xxhash-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:883dc3d3942620f4c7dbc3fd6162f50a67f050b714e47da77444e3bcea7d91cc"},
+ {file = "xxhash-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59dc8bfacf89b8f5be54d55bc3b4bd6d74d0c5320c8a63d2538ac7df5b96f1d5"},
+ {file = "xxhash-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:61e6aa1d30c2af692aa88c4dd48709426e8b37bff6a574ee2de677579c34a3d6"},
+ {file = "xxhash-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:314ec0bd21f0ee8d30f2bd82ed3759314bd317ddbbd8555668f3d20ab7a8899a"},
+ {file = "xxhash-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dad638cde3a5357ad3163b80b3127df61fb5b5e34e9e05a87697144400ba03c7"},
+ {file = "xxhash-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:eaa3ea15025b56076d806b248948612289b093e8dcda8d013776b3848dffff15"},
+ {file = "xxhash-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7deae3a312feb5c17c97cbf18129f83cbd3f1f9ec25b0f50e2bd9697befb22e7"},
+ {file = "xxhash-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:add774341c09853b1612c64a526032d95ab1683053325403e1afbe3ad2f374c5"},
+ {file = "xxhash-3.2.0-cp39-cp39-win32.whl", hash = "sha256:9b94749130ef3119375c599bfce82142c2500ef9ed3280089157ee37662a7137"},
+ {file = "xxhash-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:e57d94a1552af67f67b27db5dba0b03783ea69d5ca2af2f40e098f0ba3ce3f5f"},
+ {file = "xxhash-3.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92fd765591c83e5c5f409b33eac1d3266c03d3d11c71a7dbade36d5cdee4fbc0"},
+ {file = "xxhash-3.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8970f6a411a9839a02b23b7e90bbbba4a6de52ace009274998566dc43f36ca18"},
+ {file = "xxhash-3.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5f3e33fe6cbab481727f9aeb136a213aed7e33cd1ca27bd75e916ffacc18411"},
+ {file = "xxhash-3.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:368265392cb696dd53907e2328b5a8c1bee81cf2142d0cc743caf1c1047abb36"},
+ {file = "xxhash-3.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:3b1f3c6d67fa9f49c4ff6b25ce0e7143bab88a5bc0f4116dd290c92337d0ecc7"},
+ {file = "xxhash-3.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c5e8db6e1ee7267b7c412ad0afd5863bf7a95286b8333a5958c8097c69f94cf5"},
+ {file = "xxhash-3.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:761df3c7e2c5270088b691c5a8121004f84318177da1ca1db64222ec83c44871"},
+ {file = "xxhash-3.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2d15a707e7f689531eb4134eccb0f8bf3844bb8255ad50823aa39708d9e6755"},
+ {file = "xxhash-3.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6b2ba4ff53dd5f57d728095e3def7375eb19c90621ce3b41b256de84ec61cfd"},
+ {file = "xxhash-3.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:61b0bcf946fdfd8ab5f09179dc2b5c74d1ef47cedfc6ed0ec01fdf0ee8682dd3"},
+ {file = "xxhash-3.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f7b79f0f302396d8e0d444826ceb3d07b61977793886ebae04e82796c02e42dc"},
+ {file = "xxhash-3.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0773cd5c438ffcd5dbff91cdd503574f88a4b960e70cedeb67736583a17a918"},
+ {file = "xxhash-3.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ec1f57127879b419a2c8d2db9d9978eb26c61ae17e5972197830430ae78d25b"},
+ {file = "xxhash-3.2.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d4b15c00e807b1d3d0b612338c814739dec310b80fb069bd732b98ddc709ad7"},
+ {file = "xxhash-3.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9d3f686e3d1c8900c5459eee02b60c7399e20ec5c6402364068a343c83a61d90"},
+ {file = "xxhash-3.2.0.tar.gz", hash = "sha256:1afd47af8955c5db730f630ad53ae798cf7fae0acb64cebb3cf94d35c47dd088"},
+]
+
+[[package]]
+name = "yarl"
+version = "1.9.2"
+description = "Yet another URL library"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82"},
+ {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8"},
+ {file = "yarl-1.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9"},
+ {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560"},
+ {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bf345c3a4f5ba7f766430f97f9cc1320786f19584acc7086491f45524a551ac"},
+ {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a96c19c52ff442a808c105901d0bdfd2e28575b3d5f82e2f5fd67e20dc5f4ea"},
+ {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:891c0e3ec5ec881541f6c5113d8df0315ce5440e244a716b95f2525b7b9f3608"},
+ {file = "yarl-1.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c3a53ba34a636a256d767c086ceb111358876e1fb6b50dfc4d3f4951d40133d5"},
+ {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:566185e8ebc0898b11f8026447eacd02e46226716229cea8db37496c8cdd26e0"},
+ {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2b0738fb871812722a0ac2154be1f049c6223b9f6f22eec352996b69775b36d4"},
+ {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:32f1d071b3f362c80f1a7d322bfd7b2d11e33d2adf395cc1dd4df36c9c243095"},
+ {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3"},
+ {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56ff08ab5df8429901ebdc5d15941b59f6253393cb5da07b4170beefcf1b2528"},
+ {file = "yarl-1.9.2-cp310-cp310-win32.whl", hash = "sha256:8ea48e0a2f931064469bdabca50c2f578b565fc446f302a79ba6cc0ee7f384d3"},
+ {file = "yarl-1.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:50f33040f3836e912ed16d212f6cc1efb3231a8a60526a407aeb66c1c1956dde"},
+ {file = "yarl-1.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:646d663eb2232d7909e6601f1a9107e66f9791f290a1b3dc7057818fe44fc2b6"},
+ {file = "yarl-1.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aff634b15beff8902d1f918012fc2a42e0dbae6f469fce134c8a0dc51ca423bb"},
+ {file = "yarl-1.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a83503934c6273806aed765035716216cc9ab4e0364f7f066227e1aaea90b8d0"},
+ {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b25322201585c69abc7b0e89e72790469f7dad90d26754717f3310bfe30331c2"},
+ {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22a94666751778629f1ec4280b08eb11815783c63f52092a5953faf73be24191"},
+ {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ec53a0ea2a80c5cd1ab397925f94bff59222aa3cf9c6da938ce05c9ec20428d"},
+ {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7"},
+ {file = "yarl-1.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:832b7e711027c114d79dffb92576acd1bd2decc467dec60e1cac96912602d0e6"},
+ {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:95d2ecefbcf4e744ea952d073c6922e72ee650ffc79028eb1e320e732898d7e8"},
+ {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9"},
+ {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:783185c75c12a017cc345015ea359cc801c3b29a2966c2655cd12b233bf5a2be"},
+ {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:b8cc1863402472f16c600e3e93d542b7e7542a540f95c30afd472e8e549fc3f7"},
+ {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:822b30a0f22e588b32d3120f6d41e4ed021806418b4c9f0bc3048b8c8cb3f92a"},
+ {file = "yarl-1.9.2-cp311-cp311-win32.whl", hash = "sha256:a60347f234c2212a9f0361955007fcf4033a75bf600a33c88a0a8e91af77c0e8"},
+ {file = "yarl-1.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:be6b3fdec5c62f2a67cb3f8c6dbf56bbf3f61c0f046f84645cd1ca73532ea051"},
+ {file = "yarl-1.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38a3928ae37558bc1b559f67410df446d1fbfa87318b124bf5032c31e3447b74"},
+ {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac9bb4c5ce3975aeac288cfcb5061ce60e0d14d92209e780c93954076c7c4367"},
+ {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3da8a678ca8b96c8606bbb8bfacd99a12ad5dd288bc6f7979baddd62f71c63ef"},
+ {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13414591ff516e04fcdee8dc051c13fd3db13b673c7a4cb1350e6b2ad9639ad3"},
+ {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf74d08542c3a9ea97bb8f343d4fcbd4d8f91bba5ec9d5d7f792dbe727f88938"},
+ {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7221580dc1db478464cfeef9b03b95c5852cc22894e418562997df0d074ccc"},
+ {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:494053246b119b041960ddcd20fd76224149cfea8ed8777b687358727911dd33"},
+ {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:52a25809fcbecfc63ac9ba0c0fb586f90837f5425edfd1ec9f3372b119585e45"},
+ {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:e65610c5792870d45d7b68c677681376fcf9cc1c289f23e8e8b39c1485384185"},
+ {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:1b1bba902cba32cdec51fca038fd53f8beee88b77efc373968d1ed021024cc04"},
+ {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:662e6016409828ee910f5d9602a2729a8a57d74b163c89a837de3fea050c7582"},
+ {file = "yarl-1.9.2-cp37-cp37m-win32.whl", hash = "sha256:f364d3480bffd3aa566e886587eaca7c8c04d74f6e8933f3f2c996b7f09bee1b"},
+ {file = "yarl-1.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6a5883464143ab3ae9ba68daae8e7c5c95b969462bbe42e2464d60e7e2698368"},
+ {file = "yarl-1.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5610f80cf43b6202e2c33ba3ec2ee0a2884f8f423c8f4f62906731d876ef4fac"},
+ {file = "yarl-1.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b9a4e67ad7b646cd6f0938c7ebfd60e481b7410f574c560e455e938d2da8e0f4"},
+ {file = "yarl-1.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:83fcc480d7549ccebe9415d96d9263e2d4226798c37ebd18c930fce43dfb9574"},
+ {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fcd436ea16fee7d4207c045b1e340020e58a2597301cfbcfdbe5abd2356c2fb"},
+ {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84e0b1599334b1e1478db01b756e55937d4614f8654311eb26012091be109d59"},
+ {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3458a24e4ea3fd8930e934c129b676c27452e4ebda80fbe47b56d8c6c7a63a9e"},
+ {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:838162460b3a08987546e881a2bfa573960bb559dfa739e7800ceeec92e64417"},
+ {file = "yarl-1.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4e2d08f07a3d7d3e12549052eb5ad3eab1c349c53ac51c209a0e5991bbada78"},
+ {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:de119f56f3c5f0e2fb4dee508531a32b069a5f2c6e827b272d1e0ff5ac040333"},
+ {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:149ddea5abf329752ea5051b61bd6c1d979e13fbf122d3a1f9f0c8be6cb6f63c"},
+ {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:674ca19cbee4a82c9f54e0d1eee28116e63bc6fd1e96c43031d11cbab8b2afd5"},
+ {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:9b3152f2f5677b997ae6c804b73da05a39daa6a9e85a512e0e6823d81cdad7cc"},
+ {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5415d5a4b080dc9612b1b63cba008db84e908b95848369aa1da3686ae27b6d2b"},
+ {file = "yarl-1.9.2-cp38-cp38-win32.whl", hash = "sha256:f7a3d8146575e08c29ed1cd287068e6d02f1c7bdff8970db96683b9591b86ee7"},
+ {file = "yarl-1.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:63c48f6cef34e6319a74c727376e95626f84ea091f92c0250a98e53e62c77c72"},
+ {file = "yarl-1.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75df5ef94c3fdc393c6b19d80e6ef1ecc9ae2f4263c09cacb178d871c02a5ba9"},
+ {file = "yarl-1.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c027a6e96ef77d401d8d5a5c8d6bc478e8042f1e448272e8d9752cb0aff8b5c8"},
+ {file = "yarl-1.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3b078dbe227f79be488ffcfc7a9edb3409d018e0952cf13f15fd6512847f3f7"},
+ {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59723a029760079b7d991a401386390c4be5bfec1e7dd83e25a6a0881859e716"},
+ {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b03917871bf859a81ccb180c9a2e6c1e04d2f6a51d953e6a5cdd70c93d4e5a2a"},
+ {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1012fa63eb6c032f3ce5d2171c267992ae0c00b9e164efe4d73db818465fac3"},
+ {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74dcbfe780e62f4b5a062714576f16c2f3493a0394e555ab141bf0d746bb955"},
+ {file = "yarl-1.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c56986609b057b4839968ba901944af91b8e92f1725d1a2d77cbac6972b9ed1"},
+ {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c315df3293cd521033533d242d15eab26583360b58f7ee5d9565f15fee1bef4"},
+ {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b7232f8dfbd225d57340e441d8caf8652a6acd06b389ea2d3222b8bc89cbfca6"},
+ {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:53338749febd28935d55b41bf0bcc79d634881195a39f6b2f767870b72514caf"},
+ {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:066c163aec9d3d073dc9ffe5dd3ad05069bcb03fcaab8d221290ba99f9f69ee3"},
+ {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8288d7cd28f8119b07dd49b7230d6b4562f9b61ee9a4ab02221060d21136be80"},
+ {file = "yarl-1.9.2-cp39-cp39-win32.whl", hash = "sha256:b124e2a6d223b65ba8768d5706d103280914d61f5cae3afbc50fc3dfcc016623"},
+ {file = "yarl-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18"},
+ {file = "yarl-1.9.2.tar.gz", hash = "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571"},
+]
+
+[package.dependencies]
+idna = ">=2.0"
+multidict = ">=4.0"
+
+[[package]]
+name = "zipp"
+version = "3.16.2"
+description = "Backport of pathlib-compatible object wrapper for zip files"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"},
+ {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.8"
+content-hash = "a35a5317de1c077588121cb0c3fb6b1a079f0e9615ed5776f4f3ff5ed9aaaf60"
diff --git a/examples/instructor/pyproject.toml b/examples/instructor/pyproject.toml
new file mode 100644
index 00000000..4d11b28f
--- /dev/null
+++ b/examples/instructor/pyproject.toml
@@ -0,0 +1,29 @@
+[tool.poetry]
+name = "onnx-instructor-dev"
+version = "0.1.0"
+description = ""
+authors = ["Mohammadreza Anvari "]
+readme = "README.md"
+packages = [{include = "onnx-instructor-dev"}]
+
+[tool.poetry.dependencies]
+python = "^3.8"
+ipykernel = "^6.24.0"
+optimum = {extras = ["exporters"], version = "^1.9.1"}
+onnxruntime = "^1.15.1"
+onnxt5 = "^0.1.8"
+instructorembedding = "^1.0.1"
+sentence-transformers = "^2.2.2"
+nltk = "^3.8.1"
+jyquickhelper = "^0.4.220"
+networkx = "^3.1"
+graphviz = "^0.20.1"
+matplotlib = "^3.7.2"
+pydot = "^1.4.2"
+pygraphviz = "^1.11"
+humanize = "^4.7.0"
+
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
diff --git a/examples/replit/main.py b/examples/replit/main.py
index 725c7086..e06e45ac 100644
--- a/examples/replit/main.py
+++ b/examples/replit/main.py
@@ -38,6 +38,7 @@
class ReplitAbortException(Exception):
pass
+
## Generic Sampling Functions
diff --git a/ggml/__init__.py b/ggml/__init__.py
index 81693750..01fd2077 100644
--- a/ggml/__init__.py
+++ b/ggml/__init__.py
@@ -1,3 +1,3 @@
from .ggml import *
-__version__ = "0.0.34"
\ No newline at end of file
+__version__ = "0.0.34"
diff --git a/ggml/contrib/__init__.py b/ggml/contrib/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/ggml/contrib/onnx.py b/ggml/contrib/onnx.py
new file mode 100644
index 00000000..c411c9a2
--- /dev/null
+++ b/ggml/contrib/onnx.py
@@ -0,0 +1,5422 @@
+"""GGML ONNX backend.
+
+This module implements a GGML backend for ONNX models and operators.
+"""
+import math
+import ctypes
+import weakref
+from typing import Any, Callable, Dict, List, Optional, Tuple, Sequence, List
+from typing_extensions import TypeGuard
+
+import numpy as np
+import numpy.typing as npt
+import onnx
+from onnx.backend.base import Backend, BackendRep
+from onnx.helper import np_dtype_to_tensor_dtype, tensor_dtype_to_np_dtype
+from onnx.onnx_ml_pb2 import (
+ GraphProto,
+ ModelProto,
+ NodeProto,
+ ValueInfoProto,
+ TensorProto,
+)
+
+import ggml
+import ggml.utils
+
+onnx_dtype_map: Dict[int, npt.DTypeLike] = {
+ elem_type: np_dtype
+ for elem_type, np_dtype in onnx.mapping.TENSOR_TYPE_TO_NP_TYPE.items() # type: ignore
+}
+
+def set_ggml_tensor_data_from_numpy(
+ tensor: ggml.ggml_tensor_p, array: npt.NDArray[Any]
+):
+ array = array.astype(np.int32) if array.dtype == np.int64 else array
+ array = array.astype(np.float32) if array.dtype == np.float64 else array
+ array = array.astype(np.int8) if array.dtype == np.bool_ else array
+ ggml.ggml_backend_tensor_set(
+ tensor,
+ array.ctypes.data_as(ctypes.c_void_p),
+ 0,
+ ggml.ggml_nbytes(tensor),
+ )
+
+def get_ggml_tensor_data_as_numpy(
+ tensor: ggml.ggml_tensor_p,
+ shape: Optional[Tuple[int, ...]] = None,
+) -> npt.NDArray[Any]:
+ np_dtype = get_tensor_dtype(tensor)
+ _shape = ggml.utils.get_shape(tensor)
+ _strides = ggml.utils.get_strides(tensor)
+ size = sum(s * _strides[i] for i, s in enumerate(_shape))
+ array = np.empty(_shape, dtype=np_dtype)
+ ggml.ggml_backend_tensor_get(tensor, array.ctypes.data_as(ctypes.c_void_p), 0, ggml.ggml_nbytes(tensor))
+ return array.reshape(shape) if shape else array
+
+def map_to_ggml_type(dtype: npt.DTypeLike):
+ np_data_type_limit = np.dtype(str(dtype).replace("64", "32"))
+ ggml_type = ggml.utils.NUMPY_DTYPE_TO_GGML_TYPE.get(
+ np_data_type_limit.type,
+ ggml.utils.GGML_TYPE.F32, # TODO: Add i64 but for now, use i32 if looking for i64 or f64
+ )
+ return ggml_type
+
+
+def get_tensor_shape(tensor: ggml.ggml_tensor_p) -> Tuple[int, ...]:
+ return tuple(reversed(ggml.utils.get_shape(tensor)))
+
+
+def get_tensor_dtype(tensor: ggml.ggml_tensor_p) -> npt.DTypeLike:
+ ggml_type = ggml.utils.GGML_TYPE(tensor.contents.type)
+ if ggml_type == ggml.utils.GGML_TYPE.F16:
+ ctypes_type = ctypes.c_uint16
+ else:
+ ctypes_type = np.ctypeslib.as_ctypes_type(
+ ggml.utils.GGML_TYPE_TO_NUMPY_DTYPE[ggml_type]
+ )
+ return np.dtype(ctypes_type)
+
+
+def broadcast_tensor(
+ ctx: "GgmlOnnxExecutionContext", tensor: ggml.ggml_tensor_p, shape: Tuple[int, ...]
+):
+ ggml_type = ggml.utils.GGML_TYPE(tensor.contents.type)
+
+ if ggml_type == ggml.utils.GGML_TYPE.F32:
+ new_tensor = ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ ggml_type.value,
+ len(shape),
+ (ctypes.c_int64 * len(shape))(*shape),
+ )
+
+ new_tensor = ggml.ggml_repeat(
+ ctx.ggml_eval_context,
+ tensor,
+ new_tensor,
+ )
+ else:
+
+ @ggml.ggml_custom2_op_t
+ def custom_broadcast_to(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+
+ x = np.broadcast_to(a, shape)
+ ctx.set_tensor_data(tensor_out, x)
+
+ x = np.empty(shape, dtype=get_tensor_dtype(tensor))
+ x_t = ctx.from_numpy(x)
+ new_tensor = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ tensor,
+ custom_broadcast_to,
+ 1,
+ None,
+ )
+ ctx.refs.append(custom_broadcast_to)
+ return new_tensor
+
+
+def broadcast_shapes(
+ ctx: "GgmlOnnxExecutionContext",
+ a: ggml.ggml_tensor_p,
+ b: ggml.ggml_tensor_p,
+):
+ a_shape = get_tensor_shape(a)
+ b_shape = get_tensor_shape(b)
+
+ output_shape = tuple(
+ reversed(np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape)
+ ) # TODO: Fix this
+
+ a_shaped = a
+ b_shaped = b
+
+ if a_shape != output_shape:
+ a_shaped = broadcast_tensor(ctx, a, output_shape)
+ if b_shape != output_shape:
+ b_shaped = broadcast_tensor(ctx, b, output_shape)
+
+ return a_shaped, b_shaped
+
+
+# ------ Operators ------
+
+
+GgmlOperator = Callable[["GgmlOnnxExecutionContext", NodeProto], None]
+
+
+ggml_operators: Dict[str, GgmlOperator] = {}
+
+
+def register_ggml_operator(operator: str):
+ def inner(func: GgmlOperator):
+ ggml_operators[operator] = func
+ return func
+
+ return inner
+
+
+@register_ggml_operator("Abs")
+def ggml_operator_abs(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Abs" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+
+ abs_result = ggml.ggml_abs(
+ ctx.ggml_eval_context,
+ a,
+ )
+ ctx.ggml_tensors_dict[output_name] = abs_result
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("Add")
+def ggml_operator_add(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Add" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a, b = node_inputs
+ a, b = broadcast_shapes(ctx, a, b)
+ if ggml.utils.GGML_TYPE(a.contents.type) == ggml.utils.GGML_TYPE.I32:
+ np_dtype = get_tensor_dtype(a)
+ x = np.empty(ctx.shapes[node.input[0]], dtype=np_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_add(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.add(a, b)
+ ctx.set_tensor_data(tensor_out, x)
+
+ add_result = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context, x_t, a, b, custom_add, 1, None
+ )
+ ctx.refs.append(custom_add)
+
+ else:
+ add_result = ggml.ggml_add(
+ ctx.ggml_eval_context,
+ a,
+ b,
+ )
+ ctx.ggml_tensors_dict[output_name] = add_result
+ ctx.shapes[output_name] = tuple(reversed(add_result.contents.ne[:max(len(ctx.shapes[node.input[0]]), len(ctx.shapes[node.input[1]]))]))
+
+
+@register_ggml_operator("And")
+def ggml_operator_and(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "And" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = ctx.shapes[node.input[0]]
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = ctx.shapes[node.input[1]]
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_and(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.logical_and(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_and,
+ 1,
+ None,
+ )
+ ctx.refs.append(custom_and)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+class ArgOpsUserData(ctypes.Structure):
+ _fields_ = [
+ ("axis", ctypes.c_int),
+ ("keepdims", ctypes.c_int),
+ ("select_last_index", ctypes.c_int),
+ ]
+
+
+@register_ggml_operator("ArgMax")
+def ggml_operator_arg_max(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ArgMax" requires exactly two inputs, data and axes. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ data = node_inputs[0]
+ name = node.output[0]
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), 0)
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+ select_last_index = next(
+ (attr.i for attr in node.attribute if attr.name == "select_last_index"), 0
+ )
+
+ x_shape = ctx.shapes[node.input[0]]
+ x_dtype = get_tensor_dtype(data)
+ x_ndims = ggml.utils.get_ndims(data)
+
+ dummpy_data = np.empty(x_shape, dtype=np.int32)
+
+ if select_last_index:
+ dummpy_data = np.flip(dummpy_data, axis)
+
+ dummy_result = np.argmax(dummpy_data, axis=axis)
+
+ if select_last_index:
+ dummy_result = dummpy_data.shape[axis] - dummy_result - 1
+
+ if keepdims:
+ dummy_result = np.expand_dims(dummy_result, axis)
+
+ dummy_result = dummy_result.astype(np.int32)
+
+ x_t = ctx.from_numpy(dummy_result)
+
+ argmax_userdata = ArgOpsUserData(axis, keepdims, select_last_index)
+ userdata_p = ctypes.cast(ctypes.pointer(argmax_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom2_op_t
+ def custom_arg_max(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ArgOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ axis = userdata_data.axis
+ keepdims = userdata_data.keepdims
+ select_last_index = userdata_data.select_last_index
+
+ if select_last_index:
+ x = np.flip(x, axis)
+
+ y = np.argmax(x, axis=axis)
+
+ if select_last_index:
+ y = x.shape[axis] - y - 1
+
+ if keepdims:
+ y = np.expand_dims(y, axis)
+
+ y = y.astype(np.int32)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ data,
+ custom_arg_max,
+ 1,
+ userdata_p,
+ )
+ ctx.refs.append(custom_arg_max)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.int64))
+ ctx.refs.append(argmax_userdata)
+
+
+@register_ggml_operator("ArgMin")
+def ggml_operator_arg_min(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ArgMin" requires exactly two inputs, data and axes. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ data = node_inputs[0]
+ name = node.output[0]
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), 0)
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+ select_last_index = next(
+ (attr.i for attr in node.attribute if attr.name == "select_last_index"), 0
+ )
+
+ x_shape = self.shapes[node.input[0]]
+
+ dummpy_data = np.empty(x_shape, dtype=np.int32)
+
+ if select_last_index:
+ dummpy_data = np.flip(dummpy_data, axis)
+
+ dummy_result = np.argmin(dummpy_data, axis=axis)
+
+ if select_last_index:
+ dummy_result = dummpy_data.shape[axis] - dummy_result - 1
+
+ if keepdims:
+ dummy_result = np.expand_dims(dummy_result, axis)
+
+ dummy_result = dummy_result.astype(np.int32)
+
+ x_t = ctx.from_numpy(dummy_result)
+
+ argmax_userdata = ArgOpsUserData(axis, keepdims, select_last_index)
+ userdata_p = ctypes.cast(ctypes.pointer(argmax_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom2_op_t
+ def custom_arg_min(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ArgOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ axis = userdata_data.axis
+ keepdims = userdata_data.keepdims
+ select_last_index = userdata_data.select_last_index
+
+ if select_last_index:
+ x = np.flip(x, axis)
+
+ y = np.argmin(x, axis=axis)
+
+ if select_last_index:
+ y = x.shape[axis] - y - 1
+
+ if keepdims:
+ y = np.expand_dims(y, axis)
+
+ y = y.astype(np.int32)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ data,
+ custom_arg_min,
+ 1,
+ userdata_p,
+ )
+ ctx.refs.append(custom_arg_min)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.int64))
+ ctx.refs.append(argmax_userdata)
+
+
+@register_ggml_operator("Cast")
+def ggml_operator_cast(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Cast" requires exactly one input and a dtype. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ onnx_type = next(attr.i for attr in node.attribute if attr.name == "to")
+ onnx_type_c = ctypes.c_int(onnx_type)
+
+ a = node_inputs[0]
+ np_data_type = tensor_dtype_to_np_dtype(onnx_type)
+ np_data_type_limit = np.dtype(str(np_data_type).replace("64", "32"))
+ x = np.empty(ctx.shapes[node.input[0]], dtype=np_data_type_limit)
+
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_cast(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ dtype = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_int)).contents.value
+ tensor = ctx.to_numpy(tensor_in_2)
+ np_data_type = tensor_dtype_to_np_dtype(dtype)
+ np_data_type_limit = np.dtype(str(np_data_type).replace("64", "32"))
+
+ ctx.set_tensor_data(tensor_out, tensor.astype(np_data_type_limit))
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_cast,
+ 1,
+ ctypes.pointer(onnx_type_c),
+ )
+ ctx.set_tensor_shape(new_tensor, ctx.shapes[node.input[0]])
+
+ ctx.refs.append(custom_cast)
+ ctx.refs.append(onnx_type_c)
+
+
+@register_ggml_operator("CastLike")
+def ggml_operator_castlike(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "CastLike" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+ a, b = node_inputs
+
+ np_data_dtype = get_tensor_dtype(b)
+ np_data_type_limit = np.dtype(str(np_data_dtype).replace("64", "32"))
+
+ onnx_type = np_dtype_to_tensor_dtype(np_data_dtype)
+ onnx_type_c = ctypes.c_int(onnx_type)
+
+ x = np.empty(ctx.shapes[node.input[0]], dtype=np_data_type_limit)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_cast(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ dtype = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_int)).contents.value
+ tensor = ctx.to_numpy(tensor_in_2)
+ np_data_type = tensor_dtype_to_np_dtype(dtype)
+ np_data_type_limit = np.dtype(str(np_data_type).replace("64", "32"))
+
+ ctx.set_tensor_data(tensor_out, tensor.astype(np_data_type_limit))
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_cast,
+ 1,
+ ctypes.pointer(onnx_type_c),
+ )
+
+ ctx.refs.append(custom_cast)
+
+ ctx.refs.append(onnx_type_c)
+
+
+@register_ggml_operator("Ceil")
+def ggml_operator_ceil(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Ceil" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+ a = node_inputs[0]
+ np_dtype = get_tensor_dtype(a)
+
+ x = np.empty(ctx.shapes[node.input[0]], dtype=np_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom1_op_t
+ def custom_ceil(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ tensor = ctx.to_numpy(tensor_in_1)
+ x = np.ceil(tensor)
+ ctx.set_tensor_data(tensor_out, np.array(x))
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ custom_ceil,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_ceil)
+
+
+@register_ggml_operator("Clip")
+def ggml_operator_clip(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+ x_t, a_min, a_max = node_inputs
+ shape = ctx.shapes[node.input[0]]
+ name = node.output[0]
+
+ @ggml.ggml_custom3_op_t
+ def custom_clip(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a_min = ctx.to_numpy(tensor_in_2)
+ a_max = ctx.to_numpy(tensor_in_3)
+ a = ctx.to_numpy(tensor_in_1)
+ x = np.clip(a, a_min, a_max)
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context, x_t, a_min, a_max, custom_clip, 1, None
+ )
+ ctx.refs.append(custom_clip)
+
+
+@register_ggml_operator("Concat")
+def ggml_operator_concat(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), 0)
+ shapes = [ctx.shapes[input_] for input_ in node.input]
+
+ if not all(
+ shape[:axis] == shapes[0][:axis] and shape[axis + 1 :] == shapes[0][axis + 1 :]
+ for shape in shapes
+ ):
+ raise ValueError(
+ "All tensors must have the same shape along the specified axis."
+ )
+
+ @ggml.ggml_custom3_op_t
+ def custom_concat(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+ x = np.concatenate([a, b], axis=axis)
+ ctx.set_tensor_data(tensor_out, x)
+
+ def concat_2(name, tensor_a, tensor_b):
+ shape_a = ctx.get_tensor_shape(tensor_a)
+ shape_b = ctx.get_tensor_shape(tensor_b)
+ total_dim = shape_a[axis] + shape_b[axis]
+ output_shape = list(shape_a)
+ output_shape[axis] = total_dim
+
+ x = np.empty(output_shape, dtype=get_tensor_dtype(tensor_a))
+ x_t = ctx.from_numpy(x)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ tensor_a,
+ tensor_b,
+ custom_concat,
+ 1,
+ None,
+ )
+ return new_tensor
+
+ ctx.refs.append(custom_concat)
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = node_inputs[0]
+ for name, tensor in zip(node.input[1:], node_inputs[1:]):
+ new_tensor = concat_2(name, new_tensor, tensor)
+
+
+@register_ggml_operator("Constant")
+def ggml_operator_constant(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_attributes = node.attribute
+
+ value_attr = next(attr for attr in node_attributes if "value" in attr.name)
+ if value_attr.HasField("t"):
+ tensor = value_attr.t
+ data_type = tensor.data_type
+ dims = tensor.dims
+
+ np_data_type = tensor_dtype_to_np_dtype(data_type)
+ np_data_type_limit = np.dtype(str(np_data_type).replace("64", "32"))
+ if tensor.raw_data:
+ data_value = np.frombuffer(tensor.raw_data, dtype=np_data_type)
+ else:
+ data_value = onnx.numpy_helper.to_array(tensor)
+
+ data_value = data_value.reshape(dims)
+
+ else:
+ data_type = value_attr.type
+ np_data_type = tensor_dtype_to_np_dtype(data_type)
+ np_data_type_limit = np.dtype(str(np_data_type).replace("64", "32"))
+ if np.issubdtype(np_data_type, np.floating):
+ data_value = np.array(value_attr.f)
+ elif np.issubdtype(np_data_type, np.integer):
+ data_value = np.array(value_attr.i)
+ else:
+ raise ValueError(
+ f'Error for node "{node.name}": Constant node not set correctly or incomplete implantation.'
+ )
+
+ # clamp to 32 bit max/mins
+ if np_data_type == np.int64:
+ data_value = np.clip(data_value, np.iinfo(np.int32).min, np.iinfo(np.int32).max)
+
+ data_value = data_value.astype(np_data_type_limit)
+
+ data_tensor = ctx.from_numpy(data_value)
+
+ tensor_shape = data_value.shape
+
+ ctx.shapes[node.output[0]] = tensor_shape
+ ctx.ggml_tensors_dict[node.output[0]] = data_tensor
+
+
+@register_ggml_operator("ConstantOfShape")
+def ggml_operator_constant_of_shape(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ConstantOfShape" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ node_attributes = node.attribute
+ value_attr = next(attr for attr in node_attributes if "value" in attr.name)
+ if value_attr.HasField("t"):
+ tensor = value_attr.t
+ data_type = tensor.data_type
+ np_data_type = tensor_dtype_to_np_dtype(data_type)
+
+ if tensor.raw_data:
+ data_value = np.frombuffer(tensor.raw_data, dtype=np_data_type)
+ else:
+ data_value = onnx.numpy_helper.to_array(tensor)
+
+ else:
+ data_type = value_attr.type
+ np_data_type = tensor_dtype_to_np_dtype(data_type)
+ if np.issubdtype(np_data_type, np.floating):
+ data_value = np.array(value_attr.f)
+ elif np.issubdtype(np_data_type, np.integer):
+ data_value = np.array(value_attr.i)
+ else:
+ raise ValueError(
+ f'Error for node "{node.name}": Constant node not set correctly or incomplete implantation.'
+ )
+
+ node_inputs_0 = ctx.eval_tensor(node_inputs[0])
+ shape = tuple(ctx.to_numpy(node_inputs_0).reshape(ctx.shapes[node.input[0]]))
+ value = data_value[0]
+ new_tensor = np.full(shape, value)
+ x_t = ctx.from_numpy(new_tensor)
+ ctx.ggml_tensors_dict[node.output[0]] = x_t
+ ctx.shapes[node.output[0]] = shape
+
+
+@register_ggml_operator("Cos")
+def ggml_operator_cos(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Cos" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a = node_inputs[0]
+ a_shape = ctx.get_tensor_shape(a)
+ a_dtype = get_tensor_dtype(a)
+
+ x = np.empty(a_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_cos(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ y = np.cos(a)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_cos,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_cos)
+
+
+@register_ggml_operator("Conv")
+def ggml_operator_conv(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Conv" requires 2 - 3 inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ node_inputs_iter = iter(node_inputs)
+ x = next(node_inputs_iter)
+ x_shape = ctx.get_tensor_shape(x)
+ w = next(node_inputs_iter)
+ w_shape = ctx.get_tensor_shape(w)
+ w_dtype = get_tensor_dtype(w)
+
+ if w_dtype == np.float32:
+ w = ctx.from_numpy(ctx.to_numpy(w).astype(np.float16))
+
+ m = w_shape[0]
+ bias = next(
+ node_inputs_iter,
+ ctx.from_numpy(np.full(m, 0, dtype=get_tensor_dtype(x))),
+ )
+
+ auto_pad = next(
+ (attr.s.decode() for attr in node.attribute if attr.name == "auto_pad"),
+ "NOTSET",
+ )
+ dilations = next(
+ (attr.ints for attr in node.attribute if attr.name == "dilations"),
+ [1 for _ in x_shape[2:]],
+ )
+ group = next((attr.i for attr in node.attribute if attr.name == "group"), 1)
+ kernel_shape = next(
+ (attr.ints for attr in node.attribute if attr.name == "kernel_shape"),
+ w_shape[2:],
+ )
+ pads = next(
+ (attr.ints for attr in node.attribute if attr.name == "pads"),
+ [0 for _ in x_shape[2:]] * 2,
+ )
+ strides = next(
+ (attr.ints for attr in node.attribute if attr.name == "strides"),
+ [1 for _ in x_shape[2:]],
+ )
+
+ # Source: https://github.com/onnx/onnx/blob/main/onnx/reference/ops/op_conv.py
+
+ if auto_pad in {"SAME_LOWER", "SAME_UPPER", "VALID"}:
+ head = []
+ tail = []
+ for i in range(len(x_shape) - 2):
+ d = x_shape[i]
+ target_size = (d + strides[i] - 1) // strides[i]
+ pad_needed = (target_size - 1) * strides[i] + kernel_shape[i] - d
+ if auto_pad == "SAME_LOWER":
+ pad_head = (pad_needed + 1) // 2
+ else:
+ pad_head = pad_needed // 2
+ pad_tail = pad_needed - pad_head
+ head.append(pad_head)
+ tail.append(pad_tail)
+ pads = head + tail
+
+ if len(strides) != 2:
+ raise NotImplementedError("Cannot handle other than 2 strides")
+ if ggml.ggml_is_permuted(x):
+ x_dtype = get_tensor_dtype(x)
+ x_shape = ggml.utils.get_shape(x)
+
+ x = ggml.ggml_cpy(
+ ctx.ggml_eval_context,
+ x,
+ ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ map_to_ggml_type(x_dtype).value,
+ len(x_shape),
+ (ctypes.c_int64 * len(x_shape))(*x_shape),
+ ),
+ )
+
+ cur = ggml.ggml_conv_2d(
+ ctx.ggml_eval_context,
+ w,
+ x,
+ strides[0],
+ strides[1],
+ pads[0],
+ pads[1],
+ dilations[0],
+ dilations[1],
+ )
+ result = ggml.ggml_add(
+ ctx.ggml_eval_context,
+ cur,
+ ggml.ggml_repeat(
+ ctx.ggml_eval_context,
+ ggml.ggml_reshape_3d(ctx.ggml_eval_context, bias, 1, 1, bias.contents.ne[0]),
+ cur,
+ ),
+ )
+
+ ctx.ggml_tensors_dict[node.output[0]] = result
+
+
+@register_ggml_operator("ConvTranspose")
+def ggml_operator_convtranspose(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ConvTranspose" requires 2 - 3 inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ node_inputs_iter = iter(node_inputs)
+ x = next(node_inputs_iter)
+ x_shape = get_tensor_shape(x)
+ w = next(node_inputs_iter)
+ w_shape = get_tensor_shape(w)
+ m = w_shape[0]
+ bias = next(
+ node_inputs_iter,
+ ctx.from_numpy(np.full(m, 0, dtype=get_tensor_dtype(x))),
+ )
+
+ auto_pad = next(
+ (attr.s.decode() for attr in node.attribute if attr.name == "auto_pad"),
+ "NOTSET",
+ )
+ dilations = next(
+ (attr.ints for attr in node.attribute if attr.name == "dilations"),
+ [1 for _ in x_shape[2:]],
+ )
+ group = next((attr.i for attr in node.attribute if attr.name == "group"), 1)
+ kernel_shape = next(
+ (attr.ints for attr in node.attribute if attr.name == "kernel_shape"),
+ w_shape[2:],
+ )
+ output_padding = next(
+ (attr.ints for attr in node.attribute if attr.name == "output_padding"),
+ [0 for _ in x_shape[2:]] * 2,
+ )
+ output_shape = next(
+ (attr.ints for attr in node.attribute if attr.name == "output_shape"),
+ None,
+ )
+ pads = next(
+ (attr.ints for attr in node.attribute if attr.name == "pads"),
+ None,
+ )
+ strides = next(
+ (attr.ints for attr in node.attribute if attr.name == "strides"),
+ [1 for _ in x_shape[2:]],
+ )
+
+ # https://github.com/onnx/onnx/blob/main/onnx/reference/ops/op_conv_transpose.py
+
+ if pads is None and auto_pad not in {"SAME_UPPER", "SAME_LOWER"}:
+ pads = [0 for i in range(2 * len(strides))]
+ if pads is None:
+ if output_shape is None:
+ output_shape = [x_shape[i + 2] * strides[i] for i in range(len(strides))]
+ total_padding = [
+ strides[i] * (x_shape[i + 2] - 1)
+ + output_padding[i]
+ + ((kernel_shape[i] - 1) * dilations[i] + 1)
+ - output_shape[i]
+ for i in range(len(output_shape))
+ ]
+ pads_1 = []
+ pads_2 = []
+ for i in range(len(output_shape)):
+ if auto_pad == "SAME_UPPER":
+ pads_1.append(total_padding[i] // 2)
+ pads_2.append(total_padding[i] - (total_padding[i] // 2))
+ else:
+ pads_1.append(total_padding[i] - (total_padding[i] // 2))
+ pads_2.append(total_padding[i] // 2)
+ pads = pads_1 + pads_2
+ n_dims = len(pads) // 2
+ else:
+ n_dims = len(x_shape) - 2
+ new_pads = np.array([(pads[i], pads[i + n_dims]) for i in range(n_dims)])
+ if output_shape is None:
+ output_shape = [
+ strides[i] * (x_shape[i + 2] - 1)
+ + output_padding[i]
+ + ((kernel_shape[i] - 1) * dilations[i] + 1)
+ - new_pads[i, :].sum()
+ for i in range(n_dims)
+ ]
+
+ kernel_shape = w_shape[2:]
+ kernel_size = np.prod(kernel_shape)
+ num_output_channels = w_shape[1] * group
+ kernel_dim = num_output_channels // group * kernel_size
+
+ C = x_shape[1] # num_inputs_channels
+ m = kernel_dim # kernel_dim
+ n = np.prod(x_shape[2:]) # input_image_size
+ k = C // group
+
+ if group != 1:
+ raise NotImplementedError(
+ f'Error for node "{node.name}": Implementation for group={group} > 1 is not available yet.'
+ )
+
+ raise NotImplementedError(f'Operator "ConvTranspose" not implemented')
+
+
+class DepthToSpaceUserData(ctypes.Structure):
+ _fields_ = [
+ ("blocksize", ctypes.c_int),
+ ("mode", ctypes.c_char_p),
+ ]
+
+
+@register_ggml_operator("DepthToSpace")
+def ggml_operator_depth_to_space(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "DepthToSpace" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ blocksize = next(
+ (attr.i for attr in node.attribute if attr.name == "blocksize"), None
+ )
+
+ mode = next((attr.s for attr in node.attribute if attr.name == "mode"), b"DCR")
+
+ if blocksize is None:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "SpaceToDepth" requires "blocksize"'
+ )
+
+ N, C, H, W = get_tensor_shape(x)
+
+ new_C = C // (blocksize**2)
+ new_H = H * blocksize
+ new_W = W * blocksize
+
+ output_shape = (N, new_C, new_H, new_W)
+
+ x_t = ctx.from_numpy(np.empty(output_shape, dtype=get_tensor_dtype(x)))
+ depthtospace_userdata = DepthToSpaceUserData(blocksize, mode)
+ userdata_p = ctypes.cast(ctypes.pointer(depthtospace_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom2_op_t
+ def custom_depth_to_space(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(DepthToSpaceUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ blocksize = userdata_data.blocksize
+ mode = userdata_data.mode
+
+ N, C, H, W = x.shape
+
+ new_C = C // (blocksize**2)
+ new_H = H * blocksize
+ new_W = W * blocksize
+
+ if mode == b"DCR":
+ reshaped = x.reshape(N, blocksize, blocksize, C // (blocksize**2), H, W)
+ transposed_axes = (0, 3, 4, 1, 5, 2)
+
+ elif mode == b"CRD":
+ reshaped = x.reshape(N, C // (blocksize**2), blocksize, blocksize, H, W)
+ transposed_axes = (0, 1, 4, 2, 5, 3)
+ else:
+ raise ValueError(f"Unknown mode: {mode}")
+
+ transposed = np.transpose(reshaped, axes=transposed_axes)
+ y = transposed.reshape(N, new_C, new_H, new_W)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ x,
+ custom_depth_to_space,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_depth_to_space)
+
+ ctx.refs.append(depthtospace_userdata)
+
+
+@register_ggml_operator("Div")
+def ggml_operator_div(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Div" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+ b = node_inputs[1]
+
+ a, b = broadcast_shapes(ctx, a, b)
+ a_dtype = get_tensor_dtype(a)
+ if a_dtype == np.float32:
+ div_result = ggml.ggml_div(
+ ctx.ggml_eval_context,
+ a,
+ b,
+ )
+ else:
+ x = np.empty(ctx.get_tensor_shape(a), dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_div(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.divide(a, b)
+ ctx.set_tensor_data(tensor_out, x)
+
+ div_result = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context, x_t, a, b, custom_div, 1, None
+ )
+ ctx.refs.append(custom_div)
+ ctx.set_tensor_shape(div_result, ctx.get_tensor_shape(a))
+ ctx.ggml_tensors_dict[output_name] = div_result
+ return div_result
+
+
+class DropoutUserData(ctypes.Structure):
+ _fields_ = [
+ ("seed", ctypes.c_int),
+ ("training_mode", ctypes.c_bool),
+ ]
+
+
+@register_ggml_operator("Dropout")
+def ggml_operator_dropout(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Dropout" requires 1 - 3 inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ # Ref = https://github.com/onnx/onnx/blob/main/onnx/backend/test/case/node/dropout.py
+
+ node_inputs_iter = iter(node_inputs)
+
+ data = next(node_inputs_iter)
+ ratio = next(
+ node_inputs_iter,
+ next((attr.f for attr in node.attribute if attr.name == "ratio"), 0.5),
+ )
+ training_mode = next(node_inputs_iter, np.bool_(False))
+
+ if type(ratio) is float:
+ ratio = ctx.from_numpy(np.array([ratio]).astype(np.float32))
+
+ seed = next((attr.i for attr in node.attribute if attr.name == "seed"), 6)
+
+ if type(training_mode) is ggml.ggml_tensor_p:
+ training_mode_eval = ctx.eval_tensor(
+ training_mode,
+ )
+ training_mode = ctx.to_numpy(training_mode_eval)
+
+ droput_userdata = DropoutUserData(seed, bool(training_mode))
+ userdata_p = ctypes.cast(ctypes.pointer(droput_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom2_op_t
+ def custom_dropout_mask(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ ratio = ctx.to_numpy(tensor_in_2)
+
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(DropoutUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ seed = userdata_data.seed
+ training_mode = userdata_data.training_mode
+
+ if np.equal(0, np.array(ratio)) or training_mode is False:
+ mask = np.ones(x.shape, dtype=np.int32)
+
+ else:
+ np.random.seed(seed)
+ mask = np.random.uniform(0, 1.0, x.shape) >= ratio
+
+ ctx.set_tensor_data(tensor_out, mask)
+
+ mask = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ data,
+ ratio,
+ custom_dropout_mask,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_dropout_mask)
+
+ @ggml.ggml_custom3_op_t
+ def custom_dropout_output(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ ratio = ctx.to_numpy(tensor_in_2)
+ mask = ctx.to_numpy(tensor_in_3)
+
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(DropoutUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ training_mode = userdata_data.training_mode
+
+ if np.equal(0, np.array(ratio)) or training_mode is False:
+ y = x
+
+ else:
+ scale = 1 / (1 - ratio)
+ y = mask * x * scale
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ output = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ data,
+ ratio,
+ mask,
+ custom_dropout_output,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_dropout_output)
+
+ ctx.refs.append(droput_userdata)
+
+ if len(node.output) == 2:
+ ctx.set_tensor_dtype(node.output[1], np.dtype(np.bool_))
+ ctx.ggml_tensors_dict[node.output[0]] = output
+ ctx.ggml_tensors_dict[node.output[1]] = mask
+
+ return output, mask
+
+ ctx.ggml_tensors_dict[node.output[0]] = output
+
+
+@register_ggml_operator("Elu")
+def ggml_operator_elu(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Elu" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ x = node_inputs[0]
+ alpha = next((attr.f for attr in node.attribute if attr.name == "alpha"), 1.0)
+
+ Y = ggml.ggml_elu(
+ ctx.ggml_eval_context,
+ x,
+ )
+
+ if alpha != 1.0:
+ Y_eval = ctx.eval_tensor(
+ Y,
+ )
+ Y_np = ctx.to_numpy(Y_eval)
+ Y_alpha = np.where(Y_np < 0, alpha * Y_np, Y_np)
+
+ Y = ctx.from_numpy(Y_alpha)
+
+ ctx.ggml_tensors_dict[output_name] = Y
+
+
+@register_ggml_operator("Erf")
+def ggml_operator_erf(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Erf" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a = node_inputs[0]
+ a_shape = ctx.get_tensor_shape(a)
+ a_dtype = get_tensor_dtype(a)
+
+ x = np.empty(a_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_erf(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ y = np.vectorize(math.erf)(a)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_erf,
+ 1,
+ None,
+ )
+
+ ctx.ggml_tensors_dict[node.output[0]] = new_tensor
+
+
+@register_ggml_operator("Equal")
+def ggml_operator_equal(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Equal" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_equal(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.equal(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_equal,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_equal)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+@register_ggml_operator("Exp")
+def ggml_operator_exp(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Exp" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+ a = node_inputs[0]
+ np_dtype = get_tensor_dtype(a)
+
+ x = np.empty(get_tensor_shape(a), dtype=np_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom1_op_t
+ def custom_exp(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ tensor = ctx.to_numpy(tensor_in_1)
+ x = np.exp(tensor)
+ ctx.set_tensor_data(tensor_out, np.array(x))
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ custom_exp,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_exp)
+
+
+@register_ggml_operator("Expand")
+def ggml_operator_expand(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ target_shape = ctx.to_numpy(ctx.eval_tensor(node_inputs[1]))
+ new_shape = np.broadcast(np.empty(a_shape), np.empty(target_shape)).shape
+
+ x = np.empty(new_shape, dtype=get_tensor_dtype(node_inputs[0]))
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_expand(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ expanded = a * np.ones(new_shape, dtype=get_tensor_dtype(tensor_in_2))
+
+ ctx.set_tensor_data(tensor_out, expanded)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ custom_expand,
+ 1,
+ None,
+ )
+ ctx.refs.append(custom_expand)
+
+
+@register_ggml_operator("Flatten")
+def ggml_operator_flatten(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Flatten" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ x_shape = get_tensor_shape(x)
+ x_dtype = get_tensor_dtype(x)
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), 1)
+
+ if axis < 0:
+ axis += len(x_shape)
+
+ new_shape = (np.prod(x_shape[:axis]).astype(np.int32), -1)
+
+ x_out = np.empty(x_shape, dtype=x_dtype)
+ x_out = x_out.reshape(new_shape)
+ x_t = ctx.from_numpy(x_out)
+
+ axis_c = ctypes.c_int(axis)
+
+ @ggml.ggml_custom2_op_t
+ def custom_flatten(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ axis = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_int)).contents.value
+
+ if axis < 0:
+ axis += len(x.shape)
+ new_shape = (np.prod(x.shape[:axis]).astype(np.int32), -1)
+
+ y = x.reshape(new_shape)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ x,
+ custom_flatten,
+ 1,
+ ctypes.pointer(axis_c),
+ )
+
+ ctx.refs.append(custom_flatten)
+ ctx.refs.append(axis_c)
+
+
+@register_ggml_operator("Floor")
+def ggml_operator_floor(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Floor" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+
+ @ggml.ggml_custom1_op_t
+ def custom_floor(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ y = np.floor(x)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_floor,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_floor)
+
+
+@register_ggml_operator("Gather")
+def ggml_operator_gather(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Gather" requires exactly two inputs and one axis. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), 0)
+ axis_c = ctypes.c_int(axis)
+
+ input_shape = ctx.get_tensor_shape(node_inputs[0])
+ input_dtype = get_tensor_dtype(node_inputs[0])
+ index_shape = ctx.get_tensor_shape(node_inputs[1])
+
+ Ni = input_shape[:axis]
+ Nk = input_shape[axis + 1 :]
+ Nj = index_shape
+
+ output_shape = tuple(list(Ni) + list(Nj) + list(Nk))
+ x = np.empty(output_shape, dtype=input_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_gather(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ input_array = ctx.to_numpy(tensor_in_2)
+ index_array = ctx.to_numpy(tensor_in_3)
+ axis = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_int)).contents.value
+
+ new_array = np.take(input_array, index_array, axis=axis)
+
+ ctx.set_tensor_data(tensor_out, new_array)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_gather,
+ 1,
+ ctypes.pointer(axis_c),
+ )
+
+ ctx.refs.append(custom_gather)
+
+ ctx.refs.append(axis_c)
+
+ if output_shape == ():
+ ctx.set_tensor_shape(new_tensor, ())
+
+
+@register_ggml_operator("Gemm")
+def ggml_operator_gemm(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Gemm" requires at least two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ node_inputs_iter = iter(node_inputs)
+
+ a = next(node_inputs_iter)
+ b = next(node_inputs_iter)
+ c = next(node_inputs_iter, None)
+
+ alpha = next((attr.f for attr in node.attribute if attr.name == "alpha"), 1.0)
+ beta = next((attr.f for attr in node.attribute if attr.name == "beta"), 1.0)
+
+ transA = next((attr.i for attr in node.attribute if attr.name == "transA"), 0)
+ transB = next((attr.i for attr in node.attribute if attr.name == "transB"), 0)
+
+ b_shape = get_tensor_shape(b)
+ a_shape = get_tensor_shape(a)
+
+ # TODO: broadcast? Current broadcasting method fails during tests
+
+ a_dtype = get_tensor_dtype(a)
+ b_dtype = get_tensor_dtype(b)
+
+ a_transposed = a
+ b_transposed = b
+
+ if transA:
+ a_permute = ggml.ggml_transpose(
+ ctx.ggml_eval_context,
+ a,
+ )
+ a_shape = ggml.utils.get_shape(a_permute)
+ a_transposed = ggml.ggml_cpy(
+ ctx.ggml_eval_context,
+ a_permute,
+ ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ map_to_ggml_type(a_dtype).value,
+ len(a_shape),
+ (ctypes.c_int64 * len(a_shape))(*a_shape),
+ ),
+ )
+
+ if not transB:
+ b_permute = ggml.ggml_transpose(
+ ctx.ggml_eval_context,
+ b,
+ )
+ b_shape = ggml.utils.get_shape(b_permute)
+ b_transposed = ggml.ggml_cpy(
+ ctx.ggml_eval_context,
+ b_permute,
+ ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ map_to_ggml_type(b_dtype).value,
+ len(b_shape),
+ (ctypes.c_int64 * len(b_shape))(*b_shape),
+ ),
+ )
+
+ # Y = alpha * np.dot(A, B) + beta * C
+ # ref: https://github.com/onnx/onnx/blob/main/onnx/backend/test/case/node/gemm.py
+
+ mul_mat_result = ggml.ggml_mul_mat(
+ ctx.ggml_eval_context,
+ b_transposed,
+ a_transposed,
+ )
+
+ alpha_t = ctx.from_numpy(
+ np.full(
+ get_tensor_shape(mul_mat_result),
+ alpha,
+ dtype=get_tensor_dtype(mul_mat_result),
+ ),
+ )
+
+ mul_mat_result = ggml.ggml_mul_inplace(ctx.ggml_eval_context, mul_mat_result, alpha_t)
+
+ if c is None:
+ c = ctx.from_numpy(
+ np.full(
+ get_tensor_shape(mul_mat_result),
+ 0,
+ dtype=get_tensor_dtype(mul_mat_result),
+ ),
+ )
+
+ c, mul_mat_result = broadcast_shapes(ctx, c, mul_mat_result)
+
+ beta_t = ctx.from_numpy(
+ np.full(
+ get_tensor_shape(mul_mat_result),
+ beta,
+ dtype=get_tensor_dtype(mul_mat_result),
+ ),
+ )
+
+ mul_mat_result = ggml.ggml_add_inplace(
+ ctx.ggml_eval_context,
+ mul_mat_result,
+ ggml.ggml_mul_inplace(ctx.ggml_eval_context, c, beta_t),
+ )
+
+ ctx.ggml_tensors_dict[node.output[0]] = mul_mat_result
+
+
+@register_ggml_operator("Greater")
+def ggml_operator_greater(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Greater" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_greater(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.greater(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_greater,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_greater)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+class HardSigmoidUserData(ctypes.Structure):
+ _fields_ = [
+ ("alpha", ctypes.c_float),
+ ("beta", ctypes.c_float),
+ ]
+
+
+@register_ggml_operator("HardSigmoid")
+def ggml_operator_hardsigmoid(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Sigmoid" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ alpha = next((attr.f for attr in node.attribute if attr.name == "alpha"), 0.2)
+ beta = next((attr.f for attr in node.attribute if attr.name == "beta"), 0.5)
+
+ hsig_userdata = HardSigmoidUserData(alpha, beta)
+ userdata_p = ctypes.cast(ctypes.pointer(hsig_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom1_op_t
+ def custom_hard_sigmoid(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(HardSigmoidUserData))
+ userdata_data = userdata_data_ptr.contents
+ x = ctx.to_numpy(tensor_in_1)
+ alpha = userdata_data.alpha
+ beta = userdata_data.beta
+
+ y = np.clip((x * alpha) + beta, 0, 1)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_hard_sigmoid,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_hard_sigmoid)
+
+ ctx.refs.append(hsig_userdata)
+
+
+@register_ggml_operator("Hardmax")
+def ggml_operator_hardmax(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Hardmax" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), -1)
+ axis_c = ctypes.c_int(axis)
+
+ @ggml.ggml_custom1_op_t
+ def custom_hardmax(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ axis = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_int)).contents.value
+ x = ctx.to_numpy(tensor_in_1)
+
+ max_indices = np.argmax(x, axis=axis, keepdims=True)
+ y = np.zeros_like(x)
+ np.put_along_axis(y, max_indices, 1, axis=axis)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_hardmax,
+ 1,
+ ctypes.pointer(axis_c),
+ )
+
+ ctx.refs.append(custom_hardmax)
+
+ ctx.refs.append(axis_c)
+
+
+@register_ggml_operator("Identity")
+def ggml_operator_floor(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Identity" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ output_name = node.output[0]
+ y = ggml.ggml_dup(
+ ctx.ggml_eval_context, x
+ ) # NOTE: This will freeze the tensor in time, may not be expected.
+
+ ctx.ggml_tensors_dict[output_name] = y
+
+
+@register_ggml_operator("InstanceNormalization")
+def ggml_operator_instancenorm(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 3:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "InstanceNormalization" requires exactly three inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+ input_tensor, scale, B = node_inputs
+ epsilon = next((attr.f for attr in node.attribute if attr.name == "epsilon"), 1e-05)
+ epsilon_c = ctypes.c_double(epsilon)
+
+ @ggml.ggml_custom3_op_t
+ def custom_instancenorm(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ s = ctx.to_numpy(tensor_in_2)
+ bias = ctx.to_numpy(tensor_in_3)
+ epsilon = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_double)).contents.value
+
+ dims_x = len(x.shape)
+ axis = tuple(range(2, dims_x))
+ mean = np.mean(x, axis=axis, keepdims=True)
+ var = np.var(x, axis=axis, keepdims=True)
+
+ dim_ones = (1,) * (dims_x - 2)
+ s = s.reshape(-1, *dim_ones)
+ bias = bias.reshape(-1, *dim_ones)
+
+ y = s * (x - mean) / np.sqrt(var + epsilon) + bias
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ input_tensor,
+ scale,
+ B,
+ custom_instancenorm,
+ 1,
+ ctypes.pointer(epsilon_c),
+ )
+ ctx.refs.append(custom_instancenorm)
+ ctx.refs.append(epsilon_c)
+
+
+class LRNUserData(ctypes.Structure):
+ _fields_ = [
+ ("alpha", ctypes.c_double),
+ ("beta", ctypes.c_double),
+ ("bias", ctypes.c_double),
+ ("size", ctypes.c_int),
+ ]
+
+
+@register_ggml_operator("LRN")
+def ggml_operator_leaky_relu(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "LRN" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ alpha = next((attr.f for attr in node.attribute if attr.name == "alpha"), 0.0001)
+ beta = next((attr.f for attr in node.attribute if attr.name == "beta"), 0.75)
+ bias = next((attr.f for attr in node.attribute if attr.name == "bias"), 1.0)
+ size = next((attr.i for attr in node.attribute if attr.name == "size"), None)
+
+ if size is None:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "LRN" requires "size" attibute.'
+ )
+
+ lrn_userdata = LRNUserData(alpha, beta, bias, size)
+ userdata_p = ctypes.cast(ctypes.pointer(lrn_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom1_op_t
+ def custom_leaky_lrn(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(LRNUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ alpha = userdata_data.alpha
+ beta = userdata_data.beta
+ bias = userdata_data.bias
+ size = userdata_data.size
+
+ x = ctx.to_numpy(tensor_in_1)
+
+ square_sum = np.zeros(x.shape).astype(x.dtype)
+ for n, c, h, w in np.ndindex(x.shape):
+ square_sum[n, c, h, w] = sum(
+ x[
+ n,
+ max(0, c - int(math.floor((size - 1) / 2))) : min(
+ 5, c + int(math.ceil((size - 1) / 2)) + 1
+ ),
+ h,
+ w,
+ ]
+ ** 2
+ )
+ y = x / ((bias + (alpha / size) * square_sum) ** beta)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_leaky_lrn,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_leaky_lrn)
+ ctx.refs.append(lrn_userdata)
+
+
+@register_ggml_operator("LeakyRelu")
+def ggml_operator_leaky_relu(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "LeakyRelu" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ alpha = next((attr.f for attr in node.attribute if attr.name == "alpha"), 0.01)
+
+ axis_c = ctypes.c_double(alpha)
+
+ @ggml.ggml_custom1_op_t
+ def custom_leaky_relu(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ alpha = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_double)).contents.value
+ x = ctx.to_numpy(tensor_in_1)
+ y = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * alpha
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_leaky_relu,
+ 1,
+ ctypes.pointer(axis_c),
+ )
+
+ ctx.refs.append(custom_leaky_relu)
+ ctx.refs.append(axis_c)
+
+
+@register_ggml_operator("GreaterOrEqual")
+def ggml_operator_greater_or_equal(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "GreaterOrEqual" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_greater_equal(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.greater_equal(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_greater_equal,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_greater_equal)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+@register_ggml_operator("Less")
+def ggml_operator_less(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Less" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_less(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.less(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_less,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_less)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+@register_ggml_operator("LessOrEqual")
+def ggml_operator_less_or_equal(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "LessOrEqual" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_less_equal(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.less_equal(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_less_equal,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_less_equal)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+@register_ggml_operator("Log")
+def ggml_operator_log(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Log" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+
+ log_result = ggml.ggml_log(
+ ctx.ggml_eval_context,
+ a,
+ )
+ ctx.ggml_tensors_dict[output_name] = log_result
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("LogSoftmax")
+def ggml_operator_log_soft_max(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "LogSoftmax" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+ soft_max_result = ggml.ggml_soft_max(ctx.ggml_eval_context, a)
+ log_result = ggml.ggml_log(
+ ctx.ggml_eval_context,
+ soft_max_result,
+ )
+ ctx.ggml_tensors_dict[output_name] = log_result
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("MatMul")
+def ggml_operator_mat_mul(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "MatMul" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_name, b_name = node.input
+
+ output_name = node.output[0]
+ a, b = node_inputs
+ b_shape = get_tensor_shape(b)
+ a_shape = get_tensor_shape(a)
+
+ a_shape, b_shape = ctx.shapes[a_name], ctx.shapes[b_name]
+
+ # TODO: is this check required? broadcast alone wont pass ONNX tests but is broadcasting itself even required or should it fail if a,b are not correct?
+ try:
+ np.matmul(np.empty(a_shape), np.empty(b_shape))
+ except:
+ a, b = broadcast_shapes(ctx, a, b)
+
+ if ggml.ggml_is_permuted(a):
+ a_dtype = get_tensor_dtype(a)
+ a_shape = ggml.utils.get_shape(a)
+ a = ggml.ggml_cpy(
+ ctx.ggml_eval_context,
+ a,
+ ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ map_to_ggml_type(a_dtype).value,
+ len(a_shape),
+ (ctypes.c_int64 * len(a_shape))(*a_shape),
+ ),
+ )
+
+ b_dtype = get_tensor_dtype(b)
+
+ b_permute = ggml.ggml_transpose(
+ ctx.ggml_eval_context,
+ b,
+ )
+
+ b_shape = ggml.utils.get_shape(b_permute)
+
+ b_transposed = ggml.ggml_cpy(
+ ctx.ggml_eval_context,
+ b_permute,
+ ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ map_to_ggml_type(b_dtype).value,
+ len(b_shape),
+ (ctypes.c_int64 * len(b_shape))(*b_shape),
+ ),
+ )
+ mul_mat_result = ggml.ggml_mul_mat(
+ ctx.ggml_eval_context,
+ b_transposed,
+ a,
+ )
+
+ ctx.ggml_tensors_dict[output_name] = mul_mat_result
+ ctx.shapes[output_name] = tuple(reversed(mul_mat_result.contents.ne[:max(len(a_shape), len(b_shape))]))
+
+@register_ggml_operator("Max")
+def ggml_operator_max(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Max" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ ggml_type = map_to_ggml_type(a_dtype)
+
+ input_shapes = [get_tensor_shape(node_input) for node_input in node_inputs]
+ output_shape = input_shapes[0]
+
+ for shape in input_shapes[1:]:
+ output_shape = np.maximum(output_shape, shape)
+
+ output_shape = tuple(reversed(output_shape))
+
+ x_t = ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ ggml_type.value,
+ len(output_shape),
+ (ctypes.c_int64 * len(output_shape))(*output_shape),
+ )
+
+ @ggml.ggml_custom1_op_t
+ def custom_max(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ tensors = [ctx.to_numpy(node_input) for node_input in node_inputs]
+ x = np.max(tensors, axis=0)
+ ctx.set_tensor_data(tensor_out, np.array(x))
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ custom_max,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_max)
+
+
+@register_ggml_operator("Mean")
+def ggml_operator_mean(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Mean" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ sums = node_inputs[0]
+
+ for tensor in node_inputs[1:]:
+ sums = ggml.ggml_add(ctx.ggml_eval_context, sums, tensor)
+
+ coef_np = np.full(get_tensor_shape(sums), len(node_inputs), dtype=np.float32)
+ coef_t = ctx.from_numpy(coef_np)
+
+ mean = ggml.ggml_div(
+ ctx.ggml_eval_context,
+ sums,
+ coef_t,
+ )
+
+ ctx.ggml_tensors_dict[output_name] = mean
+
+
+@register_ggml_operator("Min")
+def ggml_operator_min(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Min" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ ggml_type = map_to_ggml_type(a_dtype)
+
+ input_shapes = [get_tensor_shape(node_input) for node_input in node_inputs]
+ output_shape = input_shapes[0]
+
+ for shape in input_shapes[1:]:
+ output_shape = np.minimum(output_shape, shape)
+
+ output_shape = tuple(reversed(output_shape))
+
+ x_t = ggml.ggml_new_tensor(
+ ctx.ggml_eval_context,
+ ggml_type.value,
+ len(output_shape),
+ (ctypes.c_int64 * len(output_shape))(*output_shape),
+ )
+
+ @ggml.ggml_custom1_op_t
+ def custom_min(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ tensors = [ctx.to_numpy(node_input) for node_input in node_inputs]
+ x = np.min(tensors, axis=0)
+ ctx.set_tensor_data(tensor_out, np.array(x))
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ custom_min,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_min)
+
+
+@register_ggml_operator("Mul")
+def ggml_operator_mul(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Mul" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+ b = node_inputs[1]
+
+ a, b = broadcast_shapes(ctx, a, b)
+
+ ggml_type_src1 = ggml.utils.GGML_TYPE(b.contents.type)
+
+ if ggml_type_src1 == ggml.utils.GGML_TYPE.F32:
+ mul_result = ggml.ggml_mul(
+ ctx.ggml_eval_context,
+ a,
+ b,
+ )
+
+ else:
+ np_dtype = get_tensor_dtype(a)
+ x = np.empty(ctx.get_tensor_shape(a), dtype=np_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_mul(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.multiply(a, b)
+ ctx.set_tensor_data(tensor_out, x)
+
+ mul_result = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context, x_t, a, b, custom_mul, 1, None
+ )
+ ctx.set_tensor_shape(mul_result, ctx.get_tensor_shape(a))
+ ctx.refs.append(custom_mul)
+
+ ctx.ggml_tensors_dict[output_name] = mul_result
+ ctx.shapes[output_name] = tuple(reversed(mul_result.contents.ne[:max(len(ctx.shapes[node.input[0]]), len(ctx.shapes[node.input[1]]))]))
+
+
+@register_ggml_operator("Neg")
+def ggml_operator_neg(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Neg" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ output_name = node.output[0]
+
+ x_neg = ggml.ggml_neg(
+ ctx.ggml_eval_context,
+ x,
+ )
+ ctx.ggml_tensors_dict[output_name] = x_neg
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("Not")
+def ggml_operator_not(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Not" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+ name = node.output[0]
+
+ @ggml.ggml_custom1_op_t
+ def custom_not(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_1)
+ x = np.logical_not(a)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ node_inputs[0],
+ custom_not,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_not)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+@register_ggml_operator("Or")
+def ggml_operator_or(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Or" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_or(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.logical_or(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_or,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_or)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+@register_ggml_operator("Pad")
+def ggml_operator_pad(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ # x, pads, value, axes
+ if len(node_inputs) < 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Pad" requires at least two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ node_inputs += [None] * (4 - len(node_inputs))
+ data, pads, value, axes = node_inputs
+ output_name = node.output[0]
+
+ input_shape = ctx.shapes[node.input[0]]
+ input_rank = len(input_shape)
+ mode = next(
+ (attr.s for attr in node.attribute if attr.name == "mode"), b"constant"
+ ).decode("utf-8")
+
+ # axes
+ axes_eval = None
+ if axes is None:
+ axes_ = list(range(input_rank))
+ else:
+ axes_eval = ctx.eval_tensor(axes)
+ axes_shape = ctx.shapes[node.input[3]]
+ axes_array = ctx.to_numpy(axes_eval).reshape(axes_shape)
+ axes_ = [axis if axis >= 0 else axis + input_rank for axis in axes_array]
+
+
+ assert pads is not None
+
+ pads_eval = ctx.eval_tensor(pads)
+ pads_shape = ctx.shapes[node.input[1]]
+ pads_ = ctx.to_numpy(pads_eval).reshape(pads_shape)
+
+ # pads is in format [x1_begin, x2_begin, ... x1_end, x2_end, ...]
+ # re-order to np.pad accepted order ((x1_begin, x1_end), (x2_begin, x2_end), ...)
+ num_axes = len(axes_)
+ pad_width: List[Tuple[int, int]] = [(0, 0) for _ in range(input_rank)]
+ for i in range(num_axes):
+ axis = axes_[i]
+ if axis < 0:
+ axis = input_rank + axis
+ pad_width[axis] = (pads_[i], pads_[i + num_axes])
+
+ expand_by = [sum(pad) for pad in pad_width]
+ prev_shape = input_shape
+
+ output_shape = [sum(x) for x in zip(prev_shape, expand_by)]
+ assert data is not None
+ a_dtype = get_tensor_dtype(data)
+ x = np.empty(output_shape, dtype=a_dtype)
+ output_shape_tracker = ctx.from_numpy(x)
+
+ constant_values = None
+ if value is not None:
+ value_shape = ctx.shapes[node.input[2]]
+ constant_values = ctx.to_numpy(ctx.eval_tensor(value)).reshape(value_shape)
+
+ @ggml.ggml_custom2_op_t
+ def custom_pad(
+ dst: ggml.ggml_tensor_p,
+ a: ggml.ggml_tensor_p,
+ b: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ b_array = ctx.to_numpy(b).reshape(input_shape)
+ if mode == "constant":
+ padded = np.pad(
+ b_array,
+ pad_width=pad_width,
+ mode=mode,
+ constant_values=constant_values,
+ ) # type: ignore
+ else:
+ padded = np.pad(
+ b_array,
+ pad_width=pad_width,
+ mode=mode,
+ ) # type: ignore
+ ctx.set_tensor_data(dst, padded)
+
+ ctx.ggml_tensors_dict[output_name] = ggml.ggml_map_custom2(
+ ctx.ggml_eval_context,
+ output_shape_tracker,
+ data,
+ custom_pad,
+ 1,
+ None,
+ )
+ ctx.refs.append(custom_pad)
+ ctx.shapes[output_name] = tuple(output_shape)
+
+
+@register_ggml_operator("PRelu")
+def ggml_operator_leaky_relu(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "PRelu" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+ x, slope = node_inputs
+
+ @ggml.ggml_custom2_op_t
+ def custom_leaky_prelu(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ slope = ctx.to_numpy(tensor_in_2)
+
+ y = np.clip(x, 0, np.inf) + np.clip(x, -np.inf, 0) * slope
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x,
+ slope,
+ custom_leaky_prelu,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_leaky_prelu)
+
+
+@register_ggml_operator("Pow")
+def ggml_operator_pow(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Pow" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x1 = node_inputs[0]
+ x2 = node_inputs[1]
+
+ @ggml.ggml_custom2_op_t
+ def custom_pow(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x1 = ctx.to_numpy(tensor_in_1)
+ x2 = ctx.to_numpy(tensor_in_2)
+
+ new_tensor = np.power(x1, x2)
+
+ ctx.set_tensor_data(tensor_out, new_tensor)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x1,
+ x2,
+ custom_pow,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_pow)
+
+
+@register_ggml_operator("RandomNormalLike")
+def ggml_operator_random_normal_like(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+ shape = ctx.get_tensor_shape(node_inputs[0])
+ dtype = get_tensor_dtype(node_inputs[0])
+
+ x = np.empty(shape, dtype=dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom1_op_t
+ def custom_random_normal(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ # TODO: use loc and scale from inputs
+ x = np.random.normal(size=shape, loc=0.0, scale=1.0).astype(dtype)
+ ctx.set_tensor_data(tensor_out, x)
+
+ ctx.refs.append(custom_random_normal)
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ custom_random_normal,
+ 1,
+ None,
+ )
+
+
+@register_ggml_operator("Range")
+def ggml_operator_range(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 3:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Range" requires exactly three inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ for node_input in node_inputs:
+ ctx.eval_tensor(node_input)
+
+ tensors = [ctx.to_numpy(node_input) for node_input in node_inputs]
+ start, stop, step = tensors
+ output_shape = (int(np.ceil((stop - start) / step)),)
+
+ x = np.empty(output_shape, dtype=step.dtype)
+ x_t = ctx.from_numpy(x)
+
+ input_tensors = ctx.from_numpy(np.array(tensors))
+
+ @ggml.ggml_custom2_op_t
+ def custom_range(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ tensors = ctx.to_numpy(tensor_in_2)
+ start_array, limit_array, delta_array = tensors
+
+ new_tensor = np.arange(start_array, limit_array, delta_array)
+
+ ctx.set_tensor_data(tensor_out, new_tensor)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensors,
+ custom_range,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_range)
+
+
+@register_ggml_operator("Reciprocal")
+def ggml_operator_reciprocal(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Reciprocal" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+
+ @ggml.ggml_custom1_op_t
+ def custom_reciprocal(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ y = np.reciprocal(x)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_reciprocal,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_reciprocal)
+
+
+class ReduceOpsUserData(ctypes.Structure):
+ _fields_ = [
+ ("axes", ctypes.POINTER(ctypes.c_int)),
+ ("axes_length", ctypes.c_int),
+ ("keepdims", ctypes.c_int),
+ ]
+
+ def __init__(self, axes, keepdims):
+ if isinstance(axes, list):
+ self.axes_length = len(axes)
+ self.axes = (ctypes.c_int * self.axes_length)(*axes)
+ else:
+ raise ValueError("axes should be a list of integers")
+
+ self.keepdims = keepdims
+
+
+@register_ggml_operator("ReduceL1")
+def ggml_operator_reduce_l1(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceL1" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return input_tensor
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_l1(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+
+ shape = tensor.shape
+ data = np.reshape(np.arange(1, np.prod(shape) + 1, dtype=np.float32), shape)
+ rl1_result = np.sum(a=np.abs(tensor), axis=axes, keepdims=keepdims)
+
+ ctx.set_tensor_data(tensor_out, rl1_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_l1,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_l1)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceL2")
+def ggml_operator_reduce_l2(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceL2" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return input_tensor
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_l2(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+
+ rl2_result = np.sqrt(np.sum(a=np.square(tensor), axis=axes, keepdims=keepdims))
+
+ ctx.set_tensor_data(tensor_out, rl2_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_l2,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_l2)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceLogSum")
+def ggml_operator_reduce_log_sum(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceLogSum" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return input_tensor
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_log_sum(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ rlogsum_result = np.log(np.sum(tensor, axis=axes, keepdims=keepdims))
+
+ ctx.set_tensor_data(tensor_out, rlogsum_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_log_sum,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_log_sum)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceLogSumExp")
+def ggml_operator_reduce_log_sum_exp(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ raise NotImplementedError(
+ f'Error for node "{node.name}": Operation "ReduceLogSumExp" is not implemented.'
+ )
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceLogSumExp" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return input_tensor
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_log_sum_exp(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ rlogsum_result = np.log(np.sum(np.exp(tensor), axis=axes, keepdims=keepdims))
+
+ ctx.set_tensor_out(tensor_out, rlogsum_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_log_sum_exp,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_log_sum_exp)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceMax")
+def ggml_operator_reduce_max(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceMax" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return input_tensor
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_max(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ rmean_result = np.max(tensor, axis=axes, keepdims=keepdims)
+
+ ctx.set_tensor_data(tensor_out, rmean_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_max,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_max)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceMean")
+def ggml_operator_reduce_mean(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceMean" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_mean(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ rmean_result = np.mean(tensor, axis=axes, keepdims=keepdims)
+
+ ctx.set_tensor_data(tensor_out, rmean_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_mean,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_mean)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceMin")
+def ggml_operator_reduce_mean(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceMin" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_min(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ rmean_result = np.minimum.reduce(tensor, axis=axes, keepdims=keepdims)
+
+ ctx.set_tensor_data(tensor_out, rmean_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_min,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_min)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceProd")
+def ggml_operator_reduce_prod(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceProd" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_prod(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ rmean_result = np.prod(tensor, axis=axes, keepdims=keepdims)
+
+ ctx.set_tensor_data(tensor_out, rmean_result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_prod,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_prod)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceSum")
+def ggml_operator_reduce_sum(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceSum" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_sum(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ result = np.sum(tensor, axis=axes, keepdims=keepdims)
+ ctx.set_tensor_data(tensor_out, result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_sum,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_sum)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("ReduceSumSquare")
+def ggml_operator_reduce_sum_square(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) > 2 or len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "ReduceSumSquare" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs[0]
+
+ noop_with_empty_axes = next(
+ (attr.i for attr in node.attribute if attr.name == "noop_with_empty_axes"), None
+ )
+
+ if noop_with_empty_axes == 1:
+ ctx.ggml_tensors_dict[node.output[0]] = input_tensor
+ return
+
+ tensor_shape = get_tensor_shape(input_tensor)
+ tensor_dtype = get_tensor_dtype(input_tensor)
+
+ axes = next((attr.ints for attr in node.attribute if attr.name == "axes"), None)
+ if not axes:
+ if len(node_inputs) > 1:
+ axes_eval = ctx.eval_tensor(node_inputs[1])
+ axes = ctx.to_numpy(axes_eval)
+ else:
+ axes = []
+
+ keepdims = next((attr.i for attr in node.attribute if attr.name == "keepdims"), 1)
+
+ rmean_userdata = ReduceOpsUserData(list(axes), keepdims)
+ userdata_p = ctypes.cast(ctypes.pointer(rmean_userdata), ctypes.c_void_p)
+
+ output_shape = tuple([1] * len(tensor_shape)) if keepdims else ()
+
+ if len(axes):
+ output_shape = list(tensor_shape)
+ sorted_axes = sorted(axes, reverse=True)
+
+ for axis in sorted_axes:
+ if keepdims:
+ output_shape[axis] = 1
+ else:
+ output_shape.pop(axis)
+
+ output_shape = tuple(output_shape)
+ x = np.empty(output_shape, dtype=tensor_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_reduce_sum_square(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(ReduceOpsUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ tensor = ctx.to_numpy(tensor_in_2)
+ axes = [userdata_data.axes[i] for i in range(userdata_data.axes_length)]
+ keepdims = userdata_data.keepdims
+
+ axes = tuple(axes) if len(axes) else None
+ result = np.sum(np.square(tensor), axis=axes, keepdims=keepdims)
+
+ ctx.set_tensor_data(tensor_out, result)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ custom_reduce_sum_square,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_reduce_sum_square)
+
+ ctx.refs.append(rmean_userdata)
+
+
+@register_ggml_operator("Relu")
+def ggml_operator_relu(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Relu" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+
+ relu_result = ggml.ggml_relu(
+ ctx.ggml_eval_context,
+ a,
+ )
+ ctx.ggml_tensors_dict[output_name] = relu_result
+
+
+@register_ggml_operator("Reshape")
+def ggml_operator_reshape(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Reshape" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ try:
+ allowzero_attr = next(
+ attr for attr in node.attribute if attr.name == "allowzero"
+ )
+ allowzero = allowzero_attr.i == 1
+ except StopIteration:
+ allowzero = False
+
+ a = node_inputs[0]
+ b = node_inputs[1]
+ eval_b = ctx.eval_tensor(
+ b,
+ )
+
+ new_shape = ctx.to_numpy(eval_b).astype(dtype=np.int32)
+
+ old_shape = get_tensor_shape(a)
+ if not allowzero:
+ keep_idxs = np.where(new_shape == 0)[0]
+ new_shape[keep_idxs] = np.array(old_shape)[keep_idxs]
+
+
+ temp_a = np.empty(old_shape, dtype=get_tensor_dtype(a))
+ x = temp_a.reshape(new_shape)
+ ctx.shapes[node.output[0]] = x.shape
+ ctx.ggml_tensors_dict[node.output[0]] = a
+
+
+@register_ggml_operator("Resize")
+def ggml_operator_resize(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] if inp != "" else None for inp in node.input]
+ node_inputs.extend([None] * (4 - len(node_inputs)))
+
+ if len(node_inputs) > 4:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Resize" requires 1-4 inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a, roi_T, scales_T, sizes_T = node_inputs
+
+ if roi_T is not None:
+ raise NotImplementedError(
+ f'Error for node "{node.name}": "roi" parameter not supported'
+ )
+ if sizes_T is not None:
+ raise NotImplementedError(
+ f'Error for node "{node.name}": "sizes" parameter not supported'
+ )
+ assert a is not None
+ assert scales_T is not None
+
+ """
+ scales_T (optional, non-differentiable) : tensor(float)
+The scale array along each dimension. It takes value greater than 0. If it's less than 1, it's sampling down, otherwise, it's upsampling. The number of elements of 'scales' should be the same as the rank of input 'X' or the length of 'axes', if provided.
+ Based on that definition, write a code that uses ggml to take tensor a and scale accordingly based on scales_T
+ """
+
+ scales_t = ctx.eval_tensor(scales_T)
+ scales = ctx.to_numpy(scales_t)
+
+ scales_shape = ctx.get_tensor_shape(scales_T)
+
+ a_shape = ctx.get_tensor_shape(a)
+ a_dtype = get_tensor_dtype(a)
+
+ if scales_shape[0] != len(a_shape):
+ raise ValueError(
+ f'Error for node "{node.name}": "scales" parameter must have the same length as the rank of input "X"'
+ )
+
+ output_shape = (a_shape * scales).astype(dtype=np.int32)
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ coordinate_transformation_mode = next(
+ (
+ attr.s.decode("utf-8")
+ for attr in node.attribute
+ if attr.name == "coordinate_transformation_mode"
+ ),
+ "half_pixel",
+ )
+ cubic_coeff_a = next(
+ (attr.f for attr in node.attribute if attr.name == "cubic_coeff_a"), -0.75
+ )
+ mode = next(
+ (attr.s.decode("utf-8") for attr in node.attribute if attr.name == "mode"),
+ "nearest",
+ )
+ nearest_mode = next(
+ (
+ attr.s.decode("utf-8")
+ for attr in node.attribute
+ if attr.name == "nearest_mode"
+ ),
+ "round_prefer_floor",
+ )
+ attribute_names = [attr.name for attr in node.attribute]
+ expected_attributes = [
+ "coordinate_transformation_mode",
+ "mode",
+ "nearest_mode",
+ ]
+
+ assert all([attribute in attribute_names for attribute in expected_attributes])
+
+ if mode not in ["nearest"]:
+ raise NotImplementedError("Only mode=nearest is supported")
+ if nearest_mode not in ["floor"]:
+ raise NotImplementedError("Only nearest_mode=floor is supported")
+ if coordinate_transformation_mode not in ["asymmetric"]:
+ raise NotImplementedError(
+ "Only coordinate_transformation_mode=asymmetric is supported"
+ )
+
+ is_integer = all(scales.astype(np.int32) - scales == 0)
+ if scales[0] == 1 and scales[1] == 1 and scales[2] == scales[3] and is_integer:
+ # Special case for 2D scaling handled by ggml_upscale
+ scale_factor = int(scales[2])
+ new_tensor = ggml.ggml_upscale(ctx.ggml_eval_context, a, scale_factor)
+ else:
+
+ @ggml.ggml_custom2_op_t
+ def custom_resize(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+
+ output_size = (scales * np.array(a.shape)).astype(int)
+ y = np.zeros(output_size)
+
+ for idx in np.ndindex(*output_size):
+ x = (np.array(idx) // scales).astype(int)
+ y[idx] = a[tuple(x)]
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_resize,
+ 1,
+ None,
+ )
+ ctx.refs.append(custom_resize)
+ ctx.ggml_tensors_dict[node.output[0]] = new_tensor
+
+
+class SeluUserData(ctypes.Structure):
+ _fields_ = [
+ ("alpha", ctypes.c_double),
+ ("gamma", ctypes.c_double),
+ ]
+
+
+@register_ggml_operator("Selu")
+def ggml_operator_selu(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Selu" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+
+ alpha = next(
+ (attr.f for attr in node.attribute if attr.name == "alpha"),
+ 1.67326319217681884765625,
+ )
+ gamma = next(
+ (attr.f for attr in node.attribute if attr.name == "gamma"),
+ 1.05070102214813232421875,
+ )
+
+ selu_userdata = SeluUserData(alpha, gamma)
+ userdata_p = ctypes.cast(ctypes.pointer(selu_userdata), ctypes.c_void_p)
+
+ @ggml.ggml_custom1_op_t
+ def custom_selu(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(SeluUserData))
+ userdata_data = userdata_data_ptr.contents
+ x = ctx.to_numpy(tensor_in_1)
+
+ alpha = userdata_data.alpha
+ gamma = userdata_data.gamma
+
+ y = (
+ np.clip(x, 0, np.inf) * gamma
+ + (np.exp(np.clip(x, -np.inf, 0)) - 1) * alpha * gamma
+ )
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_selu,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_selu)
+
+ ctx.refs.append(selu_userdata)
+
+
+@register_ggml_operator("Shape")
+def ggml_operator_shape(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Shape" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ tensor_shape = np.array(ctx.shapes[node.input[0]], dtype=np.int32)
+ name = node.output[0]
+ start = next((attr.i for attr in node.attribute if attr.name == "start"), None)
+ end = next(
+ (attr.i for attr in node.attribute if attr.name == "end"),
+ None,
+ )
+ shape_slice = tensor_shape[start:end]
+ ctx.ggml_tensors_dict[name] = ctx.from_numpy(shape_slice)
+ ctx.set_tensor_dtype(name, np.dtype(np.int64))
+ ctx.shapes[node.output[0]] = (len(shape_slice),)
+
+
+@register_ggml_operator("Sigmoid")
+def ggml_operator_sigmoid(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Sigmoid" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a = node_inputs[0]
+ a_shape = ctx.get_tensor_shape(a)
+ a_dtype = get_tensor_dtype(a)
+
+ x = np.empty(a_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_sigmoid(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ y = 1.0 / (1.0 + np.exp(np.negative(a)))
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_sigmoid,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_sigmoid)
+
+
+@register_ggml_operator("Sin")
+def ggml_operator_sin(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Sin" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a = node_inputs[0]
+ a_shape = ctx.get_tensor_shape(a)
+ a_dtype = get_tensor_dtype(a)
+
+ x = np.empty(a_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_sin(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ y = np.sin(a)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ a,
+ custom_sin,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_sin)
+
+
+@register_ggml_operator("Size")
+def ggml_operator_size(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Size" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ tensor_shape = np.array(get_tensor_shape(node_inputs[0]), dtype=np.int32)
+ name = node.output[0]
+ tensor_size_np = np.prod(tensor_shape).astype(np.int32)
+ tensor_size_np = np.array(
+ [tensor_size_np]
+ ) # Add a rank so ggml doesnt break the value, inside the custom reshape to scalar as expected TODO: Fix the ranking, ggml skalars or make sure broadcasting works fine
+ tensor_size_t = ctx.from_numpy(np.array([tensor_size_np]))
+
+ ctx.ggml_tensors_dict[name] = tensor_size_t
+ ctx.shapes[name] = (1,)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.int64))
+
+
+@register_ggml_operator("Slice")
+def ggml_operator_slice(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+ a_shape = ctx.get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+
+ dims = len(a_shape)
+
+ starts = ctx.to_numpy(ctx.eval_tensor(node_inputs[1]))
+ ends = ctx.to_numpy(ctx.eval_tensor(node_inputs[2]))
+ if len(node_inputs) >= 4:
+ axes = ctx.to_numpy(ctx.eval_tensor(node_inputs[3]))
+ else:
+ axes = list(range(len(starts)))
+
+ if len(node_inputs) == 5:
+ steps = ctx.to_numpy(ctx.eval_tensor(node_inputs[4]))
+ else:
+ steps = np.ones_like(starts)
+
+ axes = [a + dims if a < 0 else a for a in axes]
+ axes_sizes = [a_shape[i] for i in axes]
+ starts = [a + size if a < 0 else a for a, size in zip(starts, axes_sizes)]
+ ends = [a + size if a < 0 else a for a, size in zip(ends, axes_sizes)]
+
+ slices = [slice(start, end, step) for start, end, step in zip(starts, ends, steps)]
+ all_slices = []
+
+ for axis in range(dims):
+ if axis not in axes:
+ all_slices.append(slice(None))
+ else:
+ all_slices.append(slices.pop(0))
+
+ x = np.empty(a_shape, dtype=a_dtype)[tuple(all_slices)].copy()
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom2_op_t
+ def custom_slice(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ y = x[tuple(all_slices)].copy()
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2(
+ ctx.ggml_eval_context, x_t, node_inputs[0], custom_slice, 1, None
+ )
+ ctx.shapes[node.output[0]] = x.shape
+ ctx.refs.append(custom_slice)
+
+
+@register_ggml_operator("Softmax")
+def ggml_operator_softmax(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Softmax" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+
+ soft_max_result = ggml.ggml_soft_max(
+ ctx.ggml_eval_context,
+ a,
+ )
+ ctx.ggml_tensors_dict[output_name] = soft_max_result
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("Softplus")
+def ggml_operator_softplus(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Softplus" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+
+ @ggml.ggml_custom1_op_t
+ def custom_softplus(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_1)
+ y = np.log(np.exp(x) + 1)
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom1_inplace(
+ ctx.ggml_eval_context,
+ x,
+ custom_softplus,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_softplus)
+
+
+@register_ggml_operator("Softsign")
+def ggml_operator_softsign(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Softsign" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ x_shape = get_tensor_shape(x)
+ x_dtype = get_tensor_dtype(x)
+
+ # y = x / (1 + abs(x))
+ one_np = np.full(x_shape, 1, dtype=x_dtype)
+ one_t = ctx.from_numpy(one_np)
+ x_abs = ggml.ggml_abs(ctx.ggml_eval_context, x)
+ one_plus_abs = ggml.ggml_add(ctx.ggml_eval_context, one_t, x_abs)
+ y = ggml.ggml_div(ctx.ggml_eval_context, x, one_plus_abs)
+ ctx.ggml_tensors_dict[node.output[0]] = y
+
+
+@register_ggml_operator("SpaceToDepth")
+def ggml_operator_space_to_depth(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "SpaceToDepth" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ blocksize = next(
+ (attr.i for attr in node.attribute if attr.name == "blocksize"), None
+ )
+
+ if blocksize is None:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "SpaceToDepth" requires "blocksize"'
+ )
+
+ N, C, H, W = get_tensor_shape(x)
+ new_H = H // blocksize
+ new_W = W // blocksize
+ output_shape = (N, C * blocksize * blocksize, new_H, new_W)
+
+ x_t = ctx.from_numpy(np.empty(output_shape, dtype=get_tensor_dtype(x)))
+
+ blocksize_c = ctypes.c_int(blocksize)
+
+ @ggml.ggml_custom2_op_t
+ def custom_space_to_depth(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ blocksize = ctypes.cast(userdata, ctypes.POINTER(ctypes.c_int)).contents.value
+
+ N, C, H, W = x.shape
+ new_H = H // blocksize
+ new_W = W // blocksize
+
+ reshaped = x.reshape(N, C, new_H, blocksize, new_W, blocksize)
+ transposed = reshaped.transpose(
+ 0, 3, 5, 1, 2, 4
+ ) # ONNX specification TODO: Test more examples
+ y = transposed.reshape(N, C * (blocksize**2), new_H, new_W)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ x,
+ custom_space_to_depth,
+ 1,
+ ctypes.pointer(blocksize_c),
+ )
+
+ ctx.refs.append(custom_space_to_depth)
+
+ ctx.refs.append(blocksize_c)
+
+
+class SplitUserData(ctypes.Structure):
+ _fields_ = [
+ ("axis", ctypes.c_int),
+ ("split_index", ctypes.c_int),
+ ]
+
+
+@register_ggml_operator("Split")
+def ggml_operator_split(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1 or len(node_inputs) > 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Split" requires 1 - 2 inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ input_tensor = node_inputs.pop(0)
+ split_tensor = node_inputs.pop(0) if len(node_inputs) else None
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), 0)
+ num_outputs = next(
+ (attr.i for attr in node.attribute if attr.name == "num_outputs"),
+ len(node.output),
+ )
+
+ input_shape = list(get_tensor_shape(input_tensor))
+ dtype = get_tensor_dtype(input_tensor)
+
+ if split_tensor is None:
+ split_size = input_shape[axis] // num_outputs
+ remainder = input_shape[axis] % num_outputs
+ split_shapes = [list(input_shape) for _ in range(num_outputs)]
+
+ for i in range(num_outputs):
+ split_shapes[i][axis] = split_size
+ if i < remainder:
+ split_shapes[i][axis] += 1
+
+ split_shapes = [tuple(split_shape) for split_shape in split_shapes]
+
+ else:
+ split_eval = ctx.eval_tensor(
+ split_tensor,
+ )
+ split_values = ctx.to_numpy(split_eval)
+ split_shapes = [list(input_shape) for _ in range(num_outputs)]
+
+ for i, split_value in enumerate(split_values):
+ split_shapes[i][axis] = split_value
+
+ split_shapes = tuple(map(tuple, split_shapes))
+
+ split_shapes_np = np.array(split_shapes, dtype=np.int32)
+ split_shapes_t = ctx.from_numpy(split_shapes_np)
+
+ outputs = []
+
+ for split_index, split_shape in enumerate(split_shapes):
+ split_userdata = SplitUserData(axis, split_index)
+ userdata_p = ctypes.cast(ctypes.pointer(split_userdata), ctypes.c_void_p)
+
+ x_t = ctx.from_numpy(np.empty(split_shape, dtype=dtype))
+
+ @ggml.ggml_custom3_op_t
+ def custom_split(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(SplitUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ axis = userdata_data.axis
+ split_index = userdata_data.split_index
+
+ tensor = ctx.to_numpy(tensor_in_2)
+
+ split_shapes = ctx.to_numpy(tensor_in_3)
+ split_shape = list(ctx.to_numpy(tensor_in_1).shape)
+
+ split_size = split_shape[axis]
+ split_start = sum(split_shapes[i][axis] for i in range(split_index))
+ split_end = split_start + split_size
+
+ split_output = np.take(tensor, range(split_start, split_end), axis=axis)
+
+ ctx.set_tensor_data(tensor_out, split_output)
+
+ new_tensor = ctx.ggml_tensors_dict[
+ node.output[split_index]
+ ] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ input_tensor,
+ split_shapes_t,
+ custom_split,
+ 1,
+ userdata_p,
+ )
+ ctx.refs.append(custom_split)
+
+ ctx.refs.append(split_userdata)
+ outputs.append(new_tensor)
+
+
+@register_ggml_operator("Sqrt")
+def ggml_operator_sqrt(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Sqrt" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a = node_inputs[0]
+
+ sqrt_result = ggml.ggml_sqrt(
+ ctx.ggml_eval_context,
+ a,
+ )
+ ctx.ggml_tensors_dict[output_name] = sqrt_result
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("Squeeze")
+def ggml_operator_squeeze(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Squeeze" requires exactly two inputs, data and axes. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ data, axes_input = node_inputs
+ x_shape = get_tensor_shape(data)
+ x_dtype = get_tensor_dtype(data)
+
+ axes_eval = ctx.eval_tensor(
+ axes_input,
+ )
+ axes = ctx.to_numpy(axes_eval).astype(dtype=np.int32)
+ dummy_data = np.empty(x_shape, dtype=x_dtype)
+ dummy_data = np.squeeze(dummy_data, axis=axes[0])
+
+ if len(dummy_data.shape) > 4:
+ raise ValueError(
+ f'Error for node "{node.name}": {len(dummy_data.shape)}D arrays are not allowed.'
+ )
+
+ x_t = ctx.from_numpy(dummy_data)
+
+ @ggml.ggml_custom3_op_t
+ def custom_squeeze(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ axes = ctx.to_numpy(tensor_in_3)
+ y = np.squeeze(x, axis=axes[0])
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ data,
+ axes_input,
+ custom_squeeze,
+ 1,
+ None,
+ )
+ ctx.set_tensor_shape(new_tensor, dummy_data.shape)
+ ctx.refs.append(custom_squeeze)
+ ctx.shapes[node.output[0]] = dummy_data.shape
+
+
+@register_ggml_operator("Sub")
+def ggml_operator_sub(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Sub" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ a, b = node_inputs
+ a, b = broadcast_shapes(ctx, a, b)
+
+ sub_result = ggml.ggml_sub(
+ ctx.ggml_eval_context,
+ a,
+ b,
+ )
+ ctx.ggml_tensors_dict[output_name] = sub_result
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]] # TODO: Wrong
+
+
+@register_ggml_operator("Sum")
+def ggml_operator_sum(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) < 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Sum" requires at least one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ shape = get_tensor_shape(node_inputs[0])
+ dtype = get_tensor_dtype(node_inputs[0])
+
+ empty_np = np.full(shape, 0, dtype=dtype)
+ next_item = ctx.from_numpy(empty_np)
+
+ for tensor in node_inputs:
+ tensor, next_item = broadcast_shapes(ctx, tensor, next_item)
+ next_item = ggml.ggml_add(
+ ctx.ggml_eval_context,
+ tensor,
+ next_item,
+ )
+
+ ctx.ggml_tensors_dict[output_name] = next_item
+ ctx.shapes[output_name] = ctx.shapes[node.input[0]]
+
+
+@register_ggml_operator("Tanh")
+def ggml_operator_tanh(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Tanh" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x = node_inputs[0]
+ tanh_result = ggml.ggml_tanh(
+ ctx.ggml_eval_context,
+ x,
+ )
+
+ ctx.ggml_tensors_dict[node.output[0]] = tanh_result
+
+
+@register_ggml_operator("Tile")
+def ggml_operator_tile(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Tile" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x, repeats = node_inputs
+
+ repeats_eval = ctx.eval_tensor(
+ repeats,
+ )
+ repeats_vals = ctx.to_numpy(repeats_eval).astype(dtype=np.int32)
+
+ output_shape = list(get_tensor_shape(x))
+ for i in range(len(output_shape)):
+ output_shape[i] = output_shape[i] * repeats_vals[i]
+
+ x_t = ctx.from_numpy(
+ np.empty(output_shape, dtype=get_tensor_dtype(x)),
+ )
+
+ @ggml.ggml_custom3_op_t
+ def custom_tile(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ repeats = ctx.to_numpy(tensor_in_3)
+
+ y = np.tile(x, repeats)
+
+ ctx.set_tensor_data(tensor_out, y)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ x,
+ repeats,
+ custom_tile,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_tile)
+
+
+class TopKUserData(ctypes.Structure):
+ _fields_ = [
+ ("axis", ctypes.c_int),
+ ("largest", ctypes.c_int),
+ ("sorted", ctypes.c_int),
+ ("k", ctypes.c_int),
+ ]
+
+
+@register_ggml_operator("TopK")
+def ggml_operator_top_k(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "TopK" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ x, k = node_inputs
+
+ input_shape = get_tensor_shape(x)
+
+ axis = next((attr.i for attr in node.attribute if attr.name == "axis"), -1)
+ largest = next((attr.i for attr in node.attribute if attr.name == "largest"), 1)
+ sorted_flag = next((attr.i for attr in node.attribute if attr.name == "sorted"), 0)
+
+ k_eval = ctx.eval_tensor(
+ k,
+ )
+ k_np = ctx.to_numpy(k_eval)[0]
+
+ topk_userdata = TopKUserData(axis, largest, sorted_flag, k_np)
+ userdata_p = ctypes.cast(ctypes.pointer(topk_userdata), ctypes.c_void_p)
+
+ output_shape = list(input_shape)
+ output_shape[axis] = k_np
+ output_shape = tuple(output_shape)
+
+ indices_t = ctx.from_numpy(
+ np.empty(output_shape, dtype=np.int32),
+ )
+
+ values_t = ctx.from_numpy(
+ np.empty(output_shape, dtype=get_tensor_dtype(x)),
+ )
+
+ @ggml.ggml_custom2_op_t
+ def custom_top_k_indices(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(TopKUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ axis = userdata_data.axis
+ largest = bool(userdata_data.largest)
+
+ k = userdata_data.k
+
+ if largest:
+ sorted_indices = np.argsort(x, axis=axis)[:, ::-1]
+ else:
+ sorted_indices = np.argsort(x, axis=axis)
+
+ topk_indices = sorted_indices[:, :k]
+
+ ctx.set_tensor_data(tensor_out, topk_indices)
+
+ indices = ggml.ggml_map_custom2_inplace(
+ ctx.ggml_eval_context,
+ indices_t,
+ x,
+ custom_top_k_indices,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_top_k_indices)
+
+ @ggml.ggml_custom3_op_t
+ def custom_top_k_values(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ x = ctx.to_numpy(tensor_in_2)
+ topk_indices = ctx.to_numpy(tensor_in_3).astype(np.int32)
+
+ userdata_data_ptr = ctypes.cast(userdata, ctypes.POINTER(TopKUserData))
+ userdata_data = userdata_data_ptr.contents
+
+ axis = userdata_data.axis
+ sorted_flag = bool(userdata_data.sorted)
+
+ topk_values = np.take_along_axis(x, topk_indices, axis=axis)
+ if sorted_flag:
+ topk_values_sorted = np.sort(topk_values, axis=axis)
+ else:
+ topk_values_sorted = topk_values
+
+ ctx.set_tensor_data(tensor_out, topk_values_sorted)
+
+ values = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ values_t,
+ x,
+ indices,
+ custom_top_k_values,
+ 1,
+ userdata_p,
+ )
+
+ ctx.refs.append(custom_top_k_values)
+
+ ctx.ggml_tensors_dict[node.output[0]] = values
+ ctx.ggml_tensors_dict[node.output[1]] = indices
+
+ ctx.refs.append(topk_userdata)
+
+ ctx.set_tensor_dtype(node.output[1], np.dtype(np.int64))
+
+
+@register_ggml_operator("Transpose")
+def ggml_operator_transpose(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 1:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Transpose" requires exactly one input. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ output_name = node.output[0]
+ x = node_inputs[0]
+ input_shape = ctx.shapes[node.input[0]]
+
+ perm_attr = next((attr for attr in node.attribute if attr.name == "perm"), None)
+
+ if perm_attr is None:
+ perms = list(reversed(range(len(input_shape))))
+ else:
+ perms = list(perm_attr.ints)
+
+ print("perms", perms)
+
+ if len(set(perms)) != len(perms):
+ raise ValueError(
+ f'Error for node "{node.name}": Duplicate axes in "perm" attribute'
+ )
+
+ # TODO: This can probably be simplified
+ idxs = list(reversed(range(len(perms))))
+ new_idxs = [-1] * len(perms)
+ for idx, ax in enumerate(perms):
+ new_idxs[ax] = idxs[idx]
+ axes = list(reversed(new_idxs)) + list(range(4)[len(perms) :])
+
+ print("axes", axes)
+
+ ndims = len(input_shape)
+ ax0, ax1, ax2, ax3 = axes
+ transpose_result = ggml.ggml_permute(ctx.ggml_eval_context, x, ax0, ax1, ax2, ax3)
+ ctx.ggml_tensors_dict[output_name] = transpose_result
+ ctx.shapes[output_name] = tuple(reversed(transpose_result.contents.ne[:ndims]))
+
+
+@register_ggml_operator("Unsqueeze")
+def ggml_operator_unsqueeze(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Unsqueeze" requires exactly two inputs, data and axes. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ data = node_inputs[0]
+ axes_input = node_inputs[1]
+
+ x_shape = ctx.shapes[node.input[0]]
+ x_dtype = get_tensor_dtype(data)
+ x_ndims = len(x_shape)
+
+ axes_eval = ctx.eval_tensor(
+ axes_input,
+ )
+ axes = ctx.to_numpy(axes_eval).astype(dtype=np.int32)
+
+ axes_values = [ax if ax >= 0 else ax + x_ndims + 1 for ax in axes]
+ axes_values.sort()
+
+ x = np.empty(x_shape, dtype=x_dtype)
+ for axis in axes_values:
+ x = np.expand_dims(x, axis=axis)
+
+ new_shape = x.shape
+ if len(new_shape) > 4:
+ raise ValueError(
+ f'Error for node "{node.name}": {len(new_shape)}D arrays are not allowed.'
+ )
+
+ ctx.shapes[node.output[0]] = new_shape
+ ctx.ggml_tensors_dict[node.output[0]] = data
+
+
+@register_ggml_operator("Where")
+def ggml_operator_where(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 3:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Where" requires exactly three inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ c_shape, x_shape, y_shape = ctx.shapes[node.input[0]], ctx.shapes[node.input[1]], ctx.shapes[node.input[2]]
+ output_shape = np.broadcast_shapes(
+ c_shape, x_shape, y_shape
+ )
+
+ @ggml.ggml_custom3_op_t
+ def custom_where(
+ dst: ggml.ggml_tensor_p,
+ a: ggml.ggml_tensor_p,
+ b: ggml.ggml_tensor_p,
+ c: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ y = ctx.to_numpy(a).reshape(y_shape)
+ x = ctx.to_numpy(b).reshape(x_shape)
+ condition_array = ctx.to_numpy(c).reshape(c_shape)
+
+ new_tensor = np.where(condition_array, x, y)
+ ctx.set_tensor_data(dst, new_tensor)
+
+ new_tensor = ctx.ggml_tensors_dict[node.output[0]] = ggml.ggml_map_custom3(
+ ctx.ggml_eval_context,
+ node_inputs[2],
+ node_inputs[1],
+ node_inputs[0],
+ custom_where,
+ 1,
+ None,
+ )
+ ctx.shapes[node.output[0]] = output_shape
+ ctx.refs.append(custom_where)
+
+
+@register_ggml_operator("Xor")
+def ggml_operator_xor(ctx: "GgmlOnnxExecutionContext", node: NodeProto):
+ node_inputs = [ctx.ggml_tensors_dict[inp] for inp in node.input]
+
+ if len(node_inputs) != 2:
+ raise ValueError(
+ f'Error for node "{node.name}": Operation "Xor" requires exactly two inputs. Actual number of inputs: {len(node_inputs)}'
+ )
+
+ a_shape = get_tensor_shape(node_inputs[0])
+ a_dtype = get_tensor_dtype(node_inputs[0])
+ b_shape = get_tensor_shape(node_inputs[1])
+ name = node.output[0]
+
+ output_shape = np.broadcast(np.empty(a_shape), np.empty(b_shape)).shape
+
+ x = np.empty(output_shape, dtype=a_dtype)
+ x_t = ctx.from_numpy(x)
+
+ @ggml.ggml_custom3_op_t
+ def custom_xor(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in_1: ggml.ggml_tensor_p,
+ tensor_in_2: ggml.ggml_tensor_p,
+ tensor_in_3: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ a = ctx.to_numpy(tensor_in_2)
+ b = ctx.to_numpy(tensor_in_3)
+
+ x = np.logical_xor(a, b)
+
+ ctx.set_tensor_data(tensor_out, x)
+
+ new_tensor = ctx.ggml_tensors_dict[name] = ggml.ggml_map_custom3_inplace(
+ ctx.ggml_eval_context,
+ x_t,
+ node_inputs[0],
+ node_inputs[1],
+ custom_xor,
+ 1,
+ None,
+ )
+
+ ctx.refs.append(custom_xor)
+
+ ctx.set_tensor_dtype(name, np.dtype(np.bool_))
+
+
+class GgmlOnnxExecutionContext:
+ def __init__(
+ self,
+ backend: "GgmlBackendRep",
+ ggml_tensors_dict: Dict[str, ggml.ggml_tensor_p],
+ ggml_eval_context: ggml.ggml_context_p,
+ refs: List[Any],
+ max_tensors: int,
+ shapes: Dict[str, Tuple[int, ...]],
+ ):
+ self.backend = backend
+ self.ggml_tensors_dict = ggml_tensors_dict
+ self.ggml_eval_context = ggml_eval_context
+ self.refs = refs
+ self.ggml_tensor_shapes: Dict[int, Tuple[int, ...]] = {}
+ self.dtypes: Dict[str, npt.DTypeLike] = {}
+ self.max_tensors = max_tensors
+ # self.ggml_graph = ggml.ggml_new_graph_custom(self.ggml_eval_context, max_tensors, False)
+ self.ggml_graph = None
+ self.n_threads = 8
+ self.shapes = shapes
+
+ def set_tensor_shape(self, tensor: ggml.ggml_tensor_p, shape: Tuple[int, ...]):
+ key = ctypes.addressof(tensor.contents)
+ self.ggml_tensor_shapes[key] = shape
+
+ def get_tensor_shape(self, tensor: ggml.ggml_tensor_p) -> Tuple[int, ...]:
+ key = ctypes.addressof(tensor.contents)
+ if key not in self.ggml_tensor_shapes:
+ self.ggml_tensor_shapes[key] = get_tensor_shape(tensor)
+ return self.ggml_tensor_shapes[key]
+
+ def set_tensor_dtype(self, name: str, dtype: npt.DTypeLike):
+ self.dtypes[name] = dtype
+
+ def get_tensor_dtype(self, name: str) -> npt.DTypeLike:
+ tensor_dtype = get_tensor_dtype(self.ggml_tensors_dict[name])
+ return self.dtypes.get(name, tensor_dtype)
+
+ def to_numpy(self, tensor: ggml.ggml_tensor_p) -> npt.NDArray[Any]:
+ shape = self.get_tensor_shape(tensor)
+ array = get_ggml_tensor_data_as_numpy(tensor)
+ return array.reshape(shape)
+
+ def from_numpy(self, array: npt.NDArray[Any]) -> ggml.ggml_tensor_p:
+ shape = array.shape
+ tensor = ggml.utils.from_numpy(array, self.ggml_eval_context)
+
+ tensor_buffer = ggml.ggml_backend_alloc_buffer(self.backend.ggml_backend, ggml.ggml_nbytes(tensor))
+ assert tensor_buffer is not None
+ weakref.finalize(tensor, ggml.ggml_backend_buffer_free, tensor_buffer)
+ tallocr = ggml.ggml_tallocr_new(tensor_buffer)
+ ggml.ggml_tallocr_alloc(ctypes.pointer(tallocr), tensor)
+ ggml.ggml_set_input(tensor)
+ ggml.ggml_set_output(tensor)
+
+ if array.size > 0:
+ set_ggml_tensor_data_from_numpy(tensor, array)
+
+ return tensor
+
+ def eval_tensor(self, tensor: ggml.ggml_tensor_p):
+ if not tensor.contents.src[0]:
+ return tensor
+ self.ggml_graph = ggml.ggml_new_graph_custom(self.ggml_eval_context, self.max_tensors, False)
+ ggml.ggml_set_output(tensor)
+ ggml.ggml_build_forward_expand(self.ggml_graph, tensor)
+
+ default_buffer_type = ggml.ggml_backend_get_default_buffer_type(self.backend.ggml_backend)
+ assert default_buffer_type is not None
+ gallocr = ggml.ggml_gallocr_new(default_buffer_type)
+
+ if gallocr is None:
+ raise RuntimeError("Failed to create GGML graph allocator")
+
+ if not ggml.ggml_gallocr_alloc_graph(gallocr, self.ggml_graph):
+ raise RuntimeError("Failed to allocate GGML graph")
+
+ if ggml.ggml_backend_graph_compute(self.backend.ggml_backend, self.ggml_graph) != ggml.GGML_STATUS_SUCCESS:
+ raise RuntimeError("Failed to compute GGML graph")
+
+ tensor_copy = ggml.ggml_dup_tensor(self.ggml_eval_context, tensor)
+ tensor_copy_buffer = ggml.ggml_backend_alloc_buffer(self.backend.ggml_backend, ggml.ggml_nbytes(tensor_copy))
+ assert tensor_copy_buffer is not None
+ weakref.finalize(tensor_copy, ggml.ggml_backend_buffer_free, tensor_copy_buffer)
+ tallocr = ggml.ggml_tallocr_new(tensor_copy_buffer)
+ ggml.ggml_tallocr_alloc(ctypes.pointer(tallocr), tensor_copy)
+
+ ggml.ggml_backend_tensor_copy(tensor, tensor_copy)
+ self.refs.append(tensor_copy_buffer)
+
+ ggml.ggml_gallocr_free(gallocr)
+
+ return tensor_copy
+
+ def set_tensor_data(self, tensor: ggml.ggml_tensor_p, array: npt.NDArray[Any]):
+ set_ggml_tensor_data_from_numpy(tensor, array)
+
+
+class GgmlBackendRep(BackendRep):
+ def __init__(
+ self,
+ graph: GraphProto,
+ weights: Dict[str, ggml.ggml_tensor_p],
+ inputs: Sequence[ValueInfoProto],
+ outputs: Sequence[ValueInfoProto],
+ shapes: Dict[str, Tuple[int, ...]],
+ ggml_context: ggml.ggml_context_p,
+ ggml_init_params: ggml.ggml_init_params,
+ ggml_backend: ggml.ggml_backend_t,
+ ggml_weights_buffer: Any,
+ ):
+ super(GgmlBackendRep, self).__init__()
+ self.graph = graph
+ self.weights = weights
+ self.inputs = inputs
+ self.outputs = outputs
+ self.shapes = shapes
+ self.ggml_context = ggml_context
+ self.ggml_init_params = ggml_init_params
+ self.ggml_backend = ggml_backend
+ self.ggml_weights_buffer = ggml_weights_buffer
+
+ def __del__(self):
+ ggml.ggml_backend_buffer_free(self.ggml_weights_buffer)
+ ggml.ggml_free(self.ggml_context)
+
+ @staticmethod
+ def _is_list_of_arraylike(x: Any) -> TypeGuard[List[npt.ArrayLike]]:
+ return isinstance(x, list) and all(isinstance(y, (np.ndarray, list)) for y in x)
+
+ @staticmethod
+ def _is_dict_of_arraylike(x: Any) -> TypeGuard[Dict[str, npt.ArrayLike]]:
+ return (
+ isinstance(x, dict)
+ and all(isinstance(y, (np.ndarray, list)) for y in x.values())
+ and all(isinstance(k, str) for k in x.keys())
+ )
+
+ def run(self, inputs: Any, **kwargs: Any) -> Tuple[Any, ...]:
+ """Run the model with the specified inputs."""
+
+ if self._is_list_of_arraylike(inputs):
+ inputs = {k.name: v for k, v in zip(self.inputs, inputs)}
+
+ assert self._is_dict_of_arraylike(inputs)
+
+ model_graph = self.graph
+ exit_node = None
+ ggml_tensors = self.weights.copy()
+ shapes = self.shapes.copy()
+
+ ggml_input_context = ggml.ggml_init(
+ ggml.ggml_init_params(
+ mem_size=2
+ * ggml.GGML_DEFAULT_GRAPH_SIZE
+ * ggml.ggml_tensor_overhead(), # FIXME: Reduce to n inputs or combine with tensors context
+ no_alloc=True,
+ )
+ )
+ if ggml_input_context is None:
+ raise RuntimeError("Failed to initialize GGML input context")
+
+ # Create entry inputs
+ for model_input in model_graph.input:
+ input_name = model_input.name
+ input_data = np.array(inputs[input_name])
+
+ shapes[input_name] = input_data.shape
+
+ # Check if the input includes expected values
+ if input_name not in inputs:
+ raise KeyError(f'"{input_name}" must be included in the inputs.')
+
+ # Check for rank of input
+ expected_rank = len(list(model_input.type.tensor_type.shape.dim))
+ actual_rank = input_data.ndim
+
+ if expected_rank != actual_rank:
+ raise ValueError(
+ f"INVALID_ARGUMENT : Invalid rank for input: {input_name} Got: {actual_rank} Expected: {expected_rank} Please fix either the inputs or the model."
+ )
+
+ # Check for input types + allow for type casting
+ expected_dtype = onnx_dtype_map[model_input.type.tensor_type.elem_type]
+
+ try:
+ input_data.astype(expected_dtype)
+ except:
+ raise ValueError(
+ f'INVALID_ARGUMENT : Unexpected input data type for "{input_name}". Actual: {input_data.dtype}, expected: {expected_dtype}'
+ )
+
+ # Create the input tensors with the correct type/shape
+ ggml_type = map_to_ggml_type(input_data.dtype)
+ shape = tuple(reversed(input_data.shape))
+
+ # Handle scalars
+ if len(shape) == 0:
+ shape = (1,)
+
+ tensor = ggml.ggml_new_tensor(
+ ggml_input_context,
+ ggml_type.value,
+ len(shape),
+ (ctypes.c_int64 * len(shape))(*shape),
+ )
+ ggml.ggml_set_input(tensor)
+ ggml.ggml_set_output(tensor)
+
+ ggml_tensors[input_name] = tensor
+
+ ggml_input_buffer = ggml.ggml_backend_alloc_ctx_tensors(ggml_input_context, self.ggml_backend)
+
+ if ggml_input_buffer is None:
+ raise RuntimeError("Failed to allocate GGML input buffer")
+
+ # Set user inputs
+ for key, value in inputs.items():
+ tensor = ggml_tensors[key]
+ set_ggml_tensor_data_from_numpy(tensor, np.array(value))
+
+ # Define context
+ max_tensors = 8192
+ max_overhead = ggml.ggml_tensor_overhead() * max_tensors + ggml.ggml_graph_overhead_custom(max_tensors, False)
+ mem_buffer = (ctypes.c_uint8 * max_overhead)()
+ ggml_eval_context = ggml.ggml_init(
+ ggml.ggml_init_params(
+ mem_size=max_overhead, mem_buffer=ctypes.cast(mem_buffer, ctypes.c_void_p), no_alloc=True
+ )
+ )
+ if ggml_eval_context is None:
+ raise RuntimeError("Failed to initialize GGML context")
+
+ refs: List[Any] = []
+ refs.append(mem_buffer)
+
+ output_names = [output.name for output in model_graph.output]
+
+ ctx = GgmlOnnxExecutionContext(self, ggml_tensors, ggml_eval_context, refs, max_tensors, shapes)
+
+ # Build layers
+ outputs: Dict[str, ggml.ggml_tensor_p] = {}
+
+ for node in model_graph.node:
+ operator_func: Optional[GgmlOperator] = ggml_operators.get(node.op_type)
+ if operator_func is None:
+ raise NotImplementedError(f'Operator "{node.op_type}" not implemented')
+
+ operator_func(
+ ctx,
+ node,
+ )
+
+ for output in node.output:
+ if output in output_names:
+ outputs[output] = ctx.eval_tensor(ggml_tensors[output])
+
+ graph_outputs: List[npt.NDArray[Any]] = []
+ for output in self.outputs:
+ exit_node = outputs[output.name]
+ # NOTE: 0 dimension in ggml may cause bugs
+ max_tensors = np.prod(ctx.shapes[output.name]) # type: ignore
+ graph_output: npt.NDArray[Any] = (
+ ctx.to_numpy(exit_node) if max_tensors > 0 else np.empty((0))
+ ) # TODO: Add checks to convert values back to bool or etc types
+ graph_output = graph_output.astype(
+ ctx.get_tensor_dtype(output.name)
+ ) # TODO: add a second dict to keep track of types and use that instead
+
+ shape = ctx.shapes.get(output.name, ctx.get_tensor_shape(exit_node))
+ # shape = ctx.get_tensor_shape(exit_node)
+ graph_output = graph_output.reshape(shape)
+
+ graph_outputs.append(graph_output)
+
+ ggml.ggml_backend_buffer_free(ggml_input_buffer)
+ ggml.ggml_free(ggml_eval_context)
+ ggml.ggml_free(ggml_input_context)
+
+ return graph_outputs
+
+
+class GgmlRuntimeBackend(Backend):
+ @classmethod
+ def is_opset_supported(cls, model: ModelProto):
+ return True, ""
+
+ @classmethod
+ def prepare(cls, model: ModelProto, device: Optional[str] = "CPU", **kwargs: Any):
+ """Load the model and creates the ggml runtime backend representation
+ for the onnx graph.
+
+ Parameters:
+ model: ModelProto (returned by `onnx.load`),
+ device: requested device for the computation
+
+ Returns:
+ GGML Backend Representation"""
+ # This fails with large models.
+ # https://github.com/onnx/onnx/blob/b60f69412abb5393ab819b936b473f83867f6c87/onnx/backend/base.py#L85
+ # super(GgmlRuntimeBackend, cls).prepare(model, device, **kwargs)
+ ggml_backend = ggml.ggml_backend_cpu_init()
+ if ggml_backend is None:
+ raise RuntimeError("Failed to initialize GGML CPU backend")
+
+ graph = model.graph
+ weights: Dict[str, ggml.ggml_tensor_p] = {}
+ shapes: Dict[str, Tuple[int, ...]] = {}
+
+ n_tensors = len(graph.initializer)
+ ggml_init_params = ggml.ggml_init_params(
+ mem_size=n_tensors * ggml.ggml_tensor_overhead(),
+ no_alloc=True,
+ )
+
+ ggml_weights_context = ggml.ggml_init(ggml_init_params)
+ if ggml_weights_context is None:
+ raise RuntimeError("Failed to initialize GGML context")
+
+ pairs: List[Tuple[ggml.ggml_tensor_p, TensorProto]] = []
+
+ for initializer in graph.initializer:
+ name = initializer.name
+ np_array: npt.NDArray[Any] = onnx.numpy_helper.to_array(initializer) # type: ignore
+ tensor = ggml.utils.from_numpy(x=np_array, ctx=ggml_weights_context)
+ ggml.ggml_set_name(tensor, name.encode())
+ weights[name] = tensor
+ shapes[name] = np_array.shape
+ pairs.append((tensor, initializer))
+
+ ggml_weights_buffer = ggml.ggml_backend_alloc_ctx_tensors(ggml_weights_context, ggml_backend)
+
+ for tensor, initializer in pairs:
+ np_array = onnx.numpy_helper.to_array(initializer) # type: ignore
+ set_ggml_tensor_data_from_numpy(tensor, np_array)
+
+ return GgmlBackendRep(
+ graph=graph,
+ weights=weights,
+ inputs=graph.input,
+ outputs=graph.output,
+ shapes=shapes,
+ ggml_context=ggml_weights_context,
+ ggml_init_params=ggml_init_params,
+ ggml_backend=ggml_backend,
+ ggml_weights_buffer=ggml_weights_buffer,
+ )
+
+ @classmethod
+ def run_model(
+ cls, model: ModelProto, inputs: Any, device: Optional[str] = None, **kwargs
+ ) -> Tuple[Any, ...]:
+ """Compute the prediction."""
+ rep = cls.prepare(model, device, **kwargs)
+ return rep.run(inputs, **kwargs)
+
+ @classmethod
+ def run_node(
+ cls,
+ node: NodeProto,
+ inputs: Any,
+ device: Optional[str] = None,
+ outputs_info=None, # type: ignore
+ **kwargs: Any,
+ ) -> Tuple[Any, ...]:
+ """
+ This method is not implemented as it is much more efficient
+ to run a whole model than every node independently.
+ """
+ raise NotImplementedError(
+ "It is much more efficient to run a whole model than every node independently."
+ )
+
+
+class OnnxGraphRule:
+ """Base class for a graph rule which is applied to an onnx model."""
+
+ def __init__(self):
+ pass
+
+ def apply(self, model: ModelProto) -> Optional[ModelProto]:
+ """Apply the optimization rule to the given ONNX model."""
+ raise NotImplementedError()
+
+
+class OnnxGraphRuleEngine:
+ """Applies a series of OnnxGraphRule's to an ONNX model until
+ no more rules can be applied."""
+
+ def __init__(self, rules: List[OnnxGraphRule]):
+ self.rules = rules
+
+ def optimize(self, model: ModelProto) -> ModelProto:
+ """Apply the rules to the ONNX model until there no more rules
+ can be applied.
+
+ NOTE: This is a naive implementation that applies the rules in order until
+ no more rules can be applied."""
+ while True:
+ for rule in self.rules:
+ new_model = rule.apply(model)
+ if new_model is not None:
+ model = new_model
+ break
+ else:
+ break
+ return model
diff --git a/ggml/ggml.py b/ggml/ggml.py
index d09c2b53..85a9b095 100644
--- a/ggml/ggml.py
+++ b/ggml/ggml.py
@@ -57,7 +57,9 @@
import os
import sys
import ctypes
+import signal
import pathlib
+import traceback
import functools
import importlib.resources
from typing import (
@@ -75,6 +77,19 @@
from typing_extensions import TypeAlias
+if sys.platform != "win32":
+ c_globals = ctypes.CDLL(None) # POSIX
+
+
+ @ctypes.CFUNCTYPE(None, ctypes.c_int)
+ def sigabrt_handler(sig):
+ traceback.print_stack()
+ raise Exception("GGML SIGABRT")
+
+
+ c_globals.signal(signal.SIGABRT, sigabrt_handler)
+
+
# Load the library
def load_shared_library(module_name: str, lib_base_name: str):
# Construct the paths to the possible shared library names
diff --git a/ggml/utils.py b/ggml/utils.py
index afc61f03..ffee71a6 100644
--- a/ggml/utils.py
+++ b/ggml/utils.py
@@ -53,6 +53,10 @@ def to_numpy(
Returns:
Numpy array with a view of data from tensor
"""
+ data = ggml.ggml_get_data(tensor)
+ if data is None:
+ return np.array([])
+
ggml_type = GGML_TYPE(tensor.contents.type)
if ggml_type == GGML_TYPE.F16:
ctypes_type = ctypes.c_uint16
@@ -84,6 +88,12 @@ def from_numpy(x: npt.NDArray[Any], ctx: ggml.ggml_context_p) -> ggml.ggml_tenso
Returns:
New ggml tensor with data copied from x
"""
+ if x.dtype.type == np.bool_:
+ x = x.astype(np.int32)
+
+ if x.shape == ():
+ x = x.reshape((1,))
+
ggml_type = NUMPY_DTYPE_TO_GGML_TYPE[x.dtype.type]
shape = tuple(reversed(x.shape))
tensor = ggml.ggml_new_tensor(
@@ -96,7 +106,10 @@ def from_numpy(x: npt.NDArray[Any], ctx: ggml.ggml_context_p) -> ggml.ggml_tenso
*tuple(reversed(x.strides))
)
if ggml.ggml_get_data(tensor) is not None:
- to_numpy(tensor)[:] = x
+ if shape == ():
+ to_numpy(tensor)[()] = x
+ else:
+ to_numpy(tensor)[:] = x
return tensor
diff --git a/mkdocs.yml b/mkdocs.yml
index 98431153..6142fc92 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -44,6 +44,12 @@ plugins:
- social
markdown_extensions:
+ - tables
+ - attr_list
+ - pymdownx.emoji:
+ emoji_index: !!python/name:materialx.emoji.twemoji
+ emoji_generator: !!python/name:materialx.emoji.to_svg
+ - pymdownx.tilde
- pymdownx.superfences
- pymdownx.inlinehilite
- pymdownx.snippets
diff --git a/pyproject.toml b/pyproject.toml
index 8ec72a44..2104ed86 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -53,6 +53,13 @@ convert = [
"torchvision==0.15.2",
"transformers==4.29.2"
]
+onnx = ["onnx==1.14.0"]
+onnx-tests = [
+ "tabulate==0.9.0",
+ "pytest-cov==4.1.0",
+ "pytest-runner==6.0.0",
+ "onnxruntime==1.15.1",
+]
[project.urls]
Homepage = "https://github.com/abetlen/ggml-python"
diff --git a/tests/test_ggml.py b/tests/test_ggml.py
index b572d9dd..b13a44c7 100644
--- a/tests/test_ggml.py
+++ b/tests/test_ggml.py
@@ -242,3 +242,99 @@ def build_graph(
ggml.ggml_backend_buffer_free(buffer)
ggml.ggml_backend_free(backend)
ggml.ggml_free(ctx)
+
+
+def test_graph_chaining():
+ """Test for chaining together mulitple ggml graphs
+ """
+ backend = ggml.ggml_backend_cpu_init()
+ assert backend is not None
+
+ no_op_n_calls = 0
+
+ @ggml.ggml_custom1_op_t
+ def no_op(
+ tensor_out: ggml.ggml_tensor_p,
+ tensor_in: ggml.ggml_tensor_p,
+ ith: int,
+ nth: int,
+ userdata: Optional[ctypes.c_void_p],
+ ):
+ data = (ctypes.c_uint8 * ggml.ggml_nbytes(tensor_in))()
+ ggml.ggml_backend_tensor_get(
+ tensor_in,
+ ctypes.cast(data, ctypes.c_void_p),
+ 0,
+ ggml.ggml_nbytes(tensor_in),
+ )
+ tensor_out_size = ggml.ggml_nbytes(tensor_out)
+ ggml.ggml_backend_tensor_set(
+ tensor_out,
+ ctypes.cast(data, ctypes.c_void_p),
+ 0,
+ tensor_out_size,
+ )
+ nonlocal no_op_n_calls
+ no_op_n_calls += 1
+
+ params = ggml.ggml_init_params(mem_size=16 * 1024 * 1024, mem_buffer=None, no_alloc=True)
+ ctx = ggml.ggml_init(params)
+ assert ctx is not None
+ assert ggml.ggml_used_mem(ctx) == 0
+ x = ggml.ggml_new_tensor_1d(ctx, ggml.GGML_TYPE_F32, 1)
+ a = ggml.ggml_new_tensor_1d(ctx, ggml.GGML_TYPE_F32, 1)
+ b = ggml.ggml_new_tensor_1d(ctx, ggml.GGML_TYPE_F32, 1)
+ x2 = ggml.ggml_mul(ctx, x, x)
+ x2 = ggml.ggml_map_custom1(ctx, x2, no_op, 1, None)
+ f = ggml.ggml_add(ctx, ggml.ggml_mul(ctx, a, x2), b)
+
+ buffer = ggml.ggml_backend_alloc_ctx_tensors(ctx, backend)
+
+ gf = ggml.ggml_new_graph(ctx)
+ ggml.ggml_build_forward_expand(gf, f)
+
+ ggml.ggml_set_f32(x, 2.0)
+ ggml.ggml_set_f32(a, 3.0)
+ ggml.ggml_set_f32(b, 4.0)
+
+ ggml.ggml_graph_compute_with_ctx(ctx, gf, 1)
+ output = ggml.ggml_get_f32_1d(f, 0)
+ assert output == 16.0
+ assert no_op_n_calls == 1
+
+ params_eval = ggml.ggml_init_params(mem_size=16 * 1024 * 1024, mem_buffer=None, no_alloc=True)
+ ctx_eval = ggml.ggml_init(params_eval)
+ assert ctx_eval is not None
+
+ f_copy = ggml.ggml_dup_tensor(ctx_eval, f)
+ f_buffer = ggml.ggml_backend_alloc_buffer(backend, ggml.ggml_nbytes(f_copy))
+ assert f_buffer is not None
+ tallocr = ggml.ggml_tallocr_new(f_buffer)
+ ggml.ggml_tallocr_alloc(ctypes.pointer(tallocr), f_copy)
+
+ ggml.ggml_backend_tensor_copy(f, f_copy)
+
+ params2 = ggml.ggml_init_params(mem_size=16 * 1024 * 1024, mem_buffer=None, no_alloc=True)
+
+ ctx2 = ggml.ggml_init(params2)
+ assert ctx2 is not None
+
+ g = ggml.ggml_add(ctx2, f_copy, a)
+
+ buffer2 = ggml.ggml_backend_alloc_ctx_tensors(ctx2, backend)
+
+ gf2 = ggml.ggml_new_graph(ctx2)
+ ggml.ggml_build_forward_expand(gf2, g)
+
+ ggml.ggml_graph_compute_with_ctx(ctx2, gf2, 1)
+
+ output = ggml.ggml_get_f32_1d(g, 0)
+
+ assert output == 19.0
+ assert no_op_n_calls == 1
+
+ ggml.ggml_free(ctx)
+ ggml.ggml_free(ctx2)
+ ggml.ggml_backend_buffer_free(buffer)
+ ggml.ggml_backend_buffer_free(buffer2)
+ ggml.ggml_backend_free(backend)
diff --git a/tests/test_ggml_onnx.py b/tests/test_ggml_onnx.py
new file mode 100644
index 00000000..aa9a5a3f
--- /dev/null
+++ b/tests/test_ggml_onnx.py
@@ -0,0 +1,866 @@
+import io
+
+import numpy as np
+import numpy.typing as npt
+
+import onnx
+from onnx import helper
+from onnx.onnx_pb import TensorProto
+
+import onnx.backend.test
+
+from onnxruntime import InferenceSession # type: ignore
+
+from ggml.contrib.onnx import GgmlRuntimeBackend
+
+import typing
+import onnx.onnx_pb as onnx_pb
+
+import pytest
+
+def test_ggml_onnx_runtime_basic():
+ # The name of the input tensor
+ input_name = "X"
+
+ # The name of the weights tensor
+ weight_name_a = "A"
+ weight_name_b = "B"
+
+ # The name of the output
+ output_name = "Y"
+
+ # Create the nodes (operations) in our graph
+ node1 = helper.make_node(
+ "Mul", [input_name, input_name], ["X_squared"], name="node1"
+ ) # X^2
+ node2 = helper.make_node(
+ "Mul", ["X_squared", weight_name_a], ["X_squared_times_a"], name="node2"
+ ) # X^2 * A
+ node3 = helper.make_node(
+ "Add", ["X_squared_times_a", weight_name_b], [output_name], name="node3"
+ ) # X^2 * A + B
+
+ # Define the tensors (values) in our graph
+ X_value_info = helper.make_tensor_value_info(
+ input_name, TensorProto.FLOAT, [None, 1]
+ )
+
+ output_value_info = helper.make_tensor_value_info(
+ output_name, TensorProto.FLOAT, [None, 1]
+ )
+
+ # Set A and B as parameters/weights
+ weights_a = np.ones(1, dtype=float).astype(np.float32)
+ weights_b = np.ones(1, dtype=float).astype(np.float32)
+
+ A_init = helper.make_tensor(
+ weight_name_a,
+ TensorProto.FLOAT,
+ [
+ 1,
+ ],
+ weights_a,
+ )
+ B_init = helper.make_tensor(
+ weight_name_b,
+ TensorProto.FLOAT,
+ [
+ 1,
+ ],
+ weights_b,
+ )
+
+ # Create the graph (model).
+ graph_def = helper.make_graph(
+ [node1, node2, node3],
+ "simple_expression_model",
+ [X_value_info],
+ [output_value_info],
+ [A_init, B_init],
+ )
+
+ model_def = helper.make_model(graph_def, producer_name="onnx-simple-expression")
+
+ input_data = {"X": np.array([[6.0]], dtype=np.float32)}
+
+ f = io.BytesIO()
+ onnx.save(model_def, f)
+
+ runtime_result = InferenceSession(f.getvalue()).run(None, input_data)
+
+ ggml_dummy_model = GgmlRuntimeBackend.prepare(model_def)
+ ggml_result = ggml_dummy_model.run(input_data)
+ assert ggml_result == runtime_result
+
+
+class OnnxModelBuilder:
+ """Helper class to build ONNX models."""
+
+ def __init__(self, name: str):
+ self.name = name
+ self.nodes: typing.List[onnx_pb.NodeProto] = []
+ self.inputs: typing.List[onnx_pb.ValueInfoProto] = []
+ self.outputs: typing.List[onnx_pb.ValueInfoProto] = []
+ self.initializers: typing.List[onnx_pb.TensorProto] = []
+ self.counter = 0 # Counter for unique names
+
+ def add_input(
+ self,
+ name: str,
+ elem_type: int,
+ shape: typing.Optional[typing.List[typing.Union[str, int, None]]],
+ ):
+ self.inputs.append(helper.make_tensor_value_info(name, elem_type, shape))
+ return self
+
+ def add_node(
+ self,
+ op_type: str,
+ inputs: typing.List[str],
+ outputs: typing.List[str],
+ name: typing.Optional[str] = None,
+ ):
+ if name is None:
+ name = f"node{self.counter}"
+ self.counter += 1
+ self.nodes.append(helper.make_node(op_type, inputs, outputs, name=name))
+ return self
+
+ def add_initializer(
+ self, name: str, data_type: int, dims: typing.Sequence[int], vals: typing.Any
+ ):
+ self.initializers.append(helper.make_tensor(name, data_type, dims, vals))
+ return self
+
+ def add_output(
+ self, name: str, elem_type: int, shape: typing.Optional[typing.List[typing.Union[str, int, None]]]
+ ):
+ self.outputs.append(helper.make_tensor_value_info(name, elem_type, shape))
+ return self
+
+ def build_graph(self):
+ return helper.make_graph(
+ self.nodes, self.name, self.inputs, self.outputs, self.initializers
+ )
+
+ def build_model(self, name: typing.Optional[str] = None):
+ return helper.make_model(self.build_graph(), producer_name=name or self.name)
+
+ @staticmethod
+ def model_bytes(model: onnx_pb.ModelProto) -> bytes:
+ f = io.BytesIO()
+ onnx.save(model, f)
+ return f.getvalue()
+
+
+def build_simple_graph():
+ builder = OnnxModelBuilder("simple_expression_model")
+ builder.add_input("X", TensorProto.FLOAT, [None, 1])
+ builder.add_initializer("A", TensorProto.FLOAT, [1], np.ones(1, dtype=float).astype(np.float32))
+ builder.add_initializer("B", TensorProto.FLOAT, [1], np.ones(1, dtype=float).astype(np.float32))
+ builder.add_node("Mul", ["X", "X"], ["X_squared"])
+ builder.add_node("Mul", ["X_squared", "A"], ["X_squared_times_a"])
+ builder.add_node("Add", ["X_squared_times_a", "B"], ["Y"])
+ builder.add_output("Y", TensorProto.FLOAT, [None, 1])
+ return builder.build_model()
+
+
+def build_2d_graph():
+ builder = OnnxModelBuilder("simple_expression_model")
+ builder.add_input("X", TensorProto.FLOAT, [None, 2])
+ builder.add_initializer("A", TensorProto.FLOAT, [2], np.ones(2, dtype=float).astype(np.float32))
+ builder.add_initializer("B", TensorProto.FLOAT, [2], np.ones(2, dtype=float).astype(np.float32))
+ builder.add_node("Mul", ["X", "X"], ["X_squared"])
+ builder.add_node("Mul", ["X_squared", "A"], ["X_squared_times_a"])
+ builder.add_node("Add", ["X_squared_times_a", "B"], ["Y"])
+ builder.add_output("Y", TensorProto.FLOAT, [None, 2])
+ return builder.build_model()
+
+def build_matmul_graph():
+ builder = OnnxModelBuilder("simple_expression_model")
+ builder.add_input("X", TensorProto.FLOAT, [None, 2])
+ builder.add_initializer("A", TensorProto.FLOAT, [2, 3], np.ones((2, 3), dtype=float).astype(np.float32))
+ builder.add_initializer("B", TensorProto.FLOAT, [3, 4], np.ones((3, 4), dtype=float).astype(np.float32))
+ builder.add_node("MatMul", ["X", "A"], ["X_times_A"])
+ builder.add_node("MatMul", ["X_times_A", "B"], ["Y"])
+ builder.add_output("Y", TensorProto.FLOAT, [None, 4])
+ return builder.build_model()
+
+
+@pytest.mark.parametrize(
+ "model, input_data", [
+ # (build_simple_graph(), {"X": np.array([[6.0]], dtype=np.float32)}),
+ # (build_2d_graph(), {"X": np.array([[6.0, 7.0]], dtype=np.float32)}),
+ (build_matmul_graph(), {"X": np.array([[6.0, 7.0]], dtype=np.float32)}),
+ ]
+)
+def test_compare_runtimes(model: onnx_pb.ModelProto, input_data: typing.Dict[str, npt.NDArray[typing.Any]]):
+ runtime_result = InferenceSession(OnnxModelBuilder.model_bytes(model)).run(None, input_data) # type: ignore
+ ggml_dummy_model = GgmlRuntimeBackend.prepare(model)
+ ggml_result = ggml_dummy_model.run(input_data)
+ assert np.array_equal(ggml_result, runtime_result)
+
+
+# def test_ggml_onnx_graph_optimization():
+# # Construct an onnx graph and optimize it
+# # The graph is of the form y = (A^T)^T * x + b
+# # the optimization should remove the transpose operations
+
+# # The name of the input tensor
+# input_name = "x"
+
+# # The name of the weights tensor
+# weight_name_a = "A"
+# weight_name_b = "b"
+
+# # The name of the output
+# output_name = "y"
+
+# # Create the nodes (operations) in our graph
+# node1 = helper.make_node(
+# "Transpose", [weight_name_a], ["A_transposed"], name="node1"
+# ) # A^T
+# node2 = helper.make_node(
+# "Transpose", ["A_transposed"], ["A_transposed_transposed"], name="node2"
+# ) # (A^T)^T
+# node3 = helper.make_node(
+# "MatMul", [input_name, "A_transposed_transposed"], ["x_times_A"], name="node3"
+# ) # x * (A^T)^T
+# node4 = helper.make_node(
+# "Add", ["x_times_A", weight_name_b], [output_name], name="node4"
+# ) # x * (A^T)^T + b
+
+# # Define the tensors (values) in our graph
+# X_value_info = helper.make_tensor_value_info(
+# input_name, TensorProto.FLOAT, [None, 32]
+# )
+
+# output_value_info = helper.make_tensor_value_info(
+# output_name, TensorProto.FLOAT, [None, 32]
+# )
+
+# # Set A and b as parameters/weights
+# weights_a = np.random.randn(32, 32).astype(np.float32)
+
+# weights_b = np.random.randn(32).astype(np.float32)
+
+# A_init = helper.make_tensor(
+# weight_name_a,
+# TensorProto.FLOAT,
+# [
+# 32,
+# 32,
+# ],
+# weights_a,
+# )
+# B_init = helper.make_tensor(
+# weight_name_b,
+# TensorProto.FLOAT,
+# [
+# 32,
+# ],
+# weights_b,
+# )
+
+# # Create the graph (model).
+# graph_def = helper.make_graph(
+# [node1, node2, node3, node4],
+# "simple_expression_model",
+# [X_value_info],
+# [output_value_info],
+# [A_init, B_init],
+# )
+
+# model_def = helper.make_model(graph_def, producer_name="onnx-simple-expression")
+
+# from typing import Optional, List
+# from ggml.contrib.onnx import OnnxGraphRuleEngine, OnnxGraphRule
+# from onnx.onnx_ml_pb2 import ModelProto, NodeProto
+
+# class TransposeIdentityRule(OnnxGraphRule):
+# """Transpose Identity Rewrite Rule
+
+# This rules removes two consecutive transpose nodes that transpose the same tensor.
+
+# ie Transpose(Transpose(x)) -> x"""
+
+# def __init__(self):
+# super().__init__()
+
+# def apply(self, model: ModelProto) -> Optional[ModelProto]:
+# # find first transpose node
+# transpose_node: Optional[NodeProto] = None
+# for node in model.graph.node:
+# if node.op_type == "Transpose":
+# transpose_node = node
+# break
+# else:
+# return None
+
+# # find a transpose node that transposes the output of the first transpose node
+# transpose_transpose_node: Optional[NodeProto] = None
+# for node in model.graph.node:
+# if (
+# node.op_type == "Transpose"
+# and node.input[0] == transpose_node.output[0]
+# ):
+# transpose_transpose_node = node
+# break
+# else:
+# return None
+
+# # Create a new node list without the two transpose nodes
+# new_nodes: List[NodeProto] = []
+# for node in model.graph.node:
+# if node not in [transpose_node, transpose_transpose_node]:
+# new_node = NodeProto()
+# new_node.CopyFrom(node)
+# new_node.input[:] = [transpose_node.input[0] if inp == transpose_transpose_node.output[0] else inp for inp in node.input]
+# new_nodes.append(new_node)
+
+# # Create the new graph
+# new_graph = helper.make_graph(
+# new_nodes,
+# model.graph.name,
+# model.graph.input,
+# model.graph.output,
+# model.graph.initializer,
+# )
+
+# # create a new model
+# new_model = helper.make_model(
+# new_graph, producer_name=model.producer_name
+# )
+
+# return new_model
+
+
+# input_data = {"x": np.random.randn(1, 32).astype(np.float32)}
+
+# f = io.BytesIO()
+# onnx.save(model_def, f)
+
+# runtime_result = InferenceSession(f.getvalue()).run(None, input_data)
+
+# ggml_dummy_model = GgmlRuntimeBackend.prepare(model_def)
+# ggml_result = ggml_dummy_model.run(input_data)
+# assert np.allclose(ggml_result[0], runtime_result[0], rtol=1e-03, atol=1e-05)
+
+# optimizer = OnnxGraphRuleEngine(
+# rules=[TransposeIdentityRule()]
+# )
+# new_model = optimizer.optimize(model=model_def)
+# assert new_model is not None
+# ggml_dummy_model_new = GgmlRuntimeBackend.prepare(new_model)
+# assert ggml_dummy_model_new is not None
+# ggml_result_new = ggml_dummy_model_new.run(input_data)
+# assert np.allclose(ggml_result_new[0], runtime_result[0], rtol=1e-03, atol=1e-05)
+# assert sum([node.op_type == "Transpose" for node in new_model.graph.node]) == 0
+
+
+# def test_ggml_onnx_runtime_quantized():
+# # Construct an onnx graph of the form Y = X * A + B
+# # and compute the result of the graph with quantized weights
+# # A and B and compare the result with the result of the
+# # unquantized graph
+
+# # Sizes: X = (32, 32), A = (32, 32), B = (32, 32)
+
+# # The expressions Y = X * A + B cannot be computed directly with quantized
+# # weights, because ggml expects the quantized weights to appear as the first
+# # input of the MatMul and Add nodes. Therefore, we rewrite the expression
+# # using the following identities:
+# # (AB)^T = B^T A^T
+# # A = (A^T)^T
+# # A + B = B + A
+# # The final expression is Y = B + (A^T X^T)^T
+
+# from typing import Optional, List, Set
+# from ggml.contrib.onnx import OnnxGraphRuleEngine, OnnxGraphRule
+# from onnx.onnx_ml_pb2 import ModelProto, NodeProto
+
+# def _depends_on_input(name: str, model: ModelProto) -> bool:
+# # Depth first search to find any node ancestor in model.graph.inputs
+# # that is an ancestor of node
+# initializers = { node.name: node for node in model.graph.initializer }
+# inputs = { node.name: node for node in model.graph.input }
+# outputs = { node.name: node for node in model.graph.output }
+# nodes = { node.name: node for node in model.graph.node }
+
+# def _dfs(name: str, visited: Set[str]) -> bool:
+# if name in visited:
+# return False
+# if name in inputs:
+# return True
+# if name not in nodes:
+# return False
+# visited.add(name)
+# for inp in nodes[name].input:
+# if inp in initializers:
+# continue
+# if inp in outputs:
+# continue
+# if _dfs(nodes[inp].name, visited):
+# return True
+# return False
+# return _dfs(name, set())
+
+# class MatMulTransposeRule(OnnxGraphRule):
+# def __init__(self):
+# super().__init__()
+
+# def apply(self, model: ModelProto) -> Optional[ModelProto]:
+# # find a matmul node
+# matmul_node: Optional[NodeProto] = None
+# for node in model.graph.node:
+# if node.op_type == "MatMul":
+# matmul_node = node
+# break
+# else:
+# return None
+
+# # get first and second input of matmul node
+# matmul_input_0 = matmul_node.input[0]
+# matmul_input_1 = matmul_node.input[1]
+
+# # check that first input is _not_ a weight or constant tensor
+# if _depends_on_input(matmul_input_0, model):
+# return None
+
+# # check that second input is a weight or constant tensor
+# if not _depends_on_input(matmul_input_1, model):
+# return None
+
+# # replace Matmul(matmul_input_0, matmul_input_1) with Transpose(MatMul(Transpose(matmul_input_1), Transpose(matmul_input_0)))
+
+# # create new transpose nodes for the inputs
+# transpose_node_0 = NodeProto()
+# transpose_node_0.CopyFrom(matmul_node)
+# transpose_node_0.op_type = "Transpose"
+# transpose_node_0.name = matmul_input_0 + "_transposed"
+# transpose_node_0.input[:] = [matmul_input_0]
+# transpose_node_0.output[:] = [matmul_input_0 + "_transposed"]
+
+# transpose_node_1 = NodeProto()
+# transpose_node_1.CopyFrom(matmul_node)
+# transpose_node_1.op_type = "Transpose"
+# transpose_node_1.name = matmul_input_1 + "_transposed"
+# transpose_node_1.input[:] = [matmul_input_1]
+# transpose_node_1.output[:] = [matmul_input_1 + "_transposed"]
+
+# # create new matmul node
+# new_matmul_node = NodeProto()
+# new_matmul_node.CopyFrom(matmul_node)
+# new_matmul_node.op_type = "MatMul"
+# new_matmul_node.name = matmul_node.name + "_inner"
+# new_matmul_node.input[:] = [transpose_node_1.output[0], transpose_node_0.output[0]]
+# new_matmul_node.output[:] = [matmul_node.output[0]]
+
+# # create final transpose node
+# final_transpose_node = NodeProto()
+# final_transpose_node.CopyFrom(matmul_node)
+# final_transpose_node.op_type = "Transpose"
+# final_transpose_node.name = matmul_node.name # this is the name of the original matmul node
+# final_transpose_node.input[:] = [new_matmul_node.output[0]]
+# final_transpose_node.output[:] = [matmul_node.output[0]]
+
+# # Create the new node list
+# new_nodes: List[NodeProto] = []
+# for node in model.graph.node:
+# if node not in [matmul_node]:
+# new_node = NodeProto()
+# new_node.CopyFrom(node)
+# new_nodes.append(new_node)
+# else:
+# new_nodes.extend([transpose_node_0, transpose_node_1, new_matmul_node, final_transpose_node])
+
+# # Create the new graph
+# new_graph = helper.make_graph(
+# new_nodes,
+# model.graph.name,
+# model.graph.input,
+# model.graph.output,
+# model.graph.initializer,
+# )
+
+# # create a new model
+# new_model = helper.make_model(
+# new_graph, producer_name=model.producer_name
+# )
+
+# return new_model
+
+# class AddAssociativityRule(OnnxGraphRule):
+# def __init__(self):
+# super().__init__()
+
+# def apply(self, model: ModelProto) -> Optional[ModelProto]:
+# # find an add node
+# add_node: Optional[NodeProto] = None
+# for node in model.graph.node:
+# if node.op_type == "Add":
+# add_node = node
+# break
+# else:
+# return None
+
+# # get first and second input of add node
+# add_input_0 = add_node.input[0]
+# add_input_1 = add_node.input[1]
+
+# # check that first input is _not_ a weight or constant tensor
+# if _depends_on_input(add_input_0, model):
+# return None
+
+# # check that second input is a weight or constant tensor
+# if not _depends_on_input(add_input_1, model):
+# return None
+
+# # replace Add(add_input_0, add_input_1) with Add(add_input_1, add_input_0)
+
+# # create new add node
+# new_add_node = NodeProto()
+# new_add_node.CopyFrom(add_node)
+# new_add_node.op_type = "Add"
+# new_add_node.name = add_node.name
+# new_add_node.input[:] = [add_input_1, add_input_0]
+# new_add_node.output[:] = [add_node.output[0]]
+
+# # Create the new node list
+# new_nodes: List[NodeProto] = []
+# for node in model.graph.node:
+# if node not in [add_node]:
+# new_node = NodeProto()
+# new_node.CopyFrom(node)
+# new_nodes.append(new_node)
+# else:
+# new_nodes.extend([new_add_node])
+
+# # Create the new graph
+# new_graph = helper.make_graph(
+# new_nodes,
+# model.graph.name,
+# model.graph.input,
+# model.graph.output,
+# model.graph.initializer,
+# )
+
+# # create a new model
+# new_model = helper.make_model(
+# new_graph, producer_name=model.producer_name
+# )
+
+# return new_model
+
+# engine = OnnxGraphRuleEngine(
+# rules=[MatMulTransposeRule(), AddAssociativityRule()]
+# )
+
+# # The name of the input tensor
+# input_name = "X"
+
+# # The name of the weights tensor
+# weight_name_a = "A"
+# weight_name_b = "B"
+
+# # The name of the output
+# output_name = "Y"
+
+# # Create the nodes (operations) in our graph Y = X * A + B
+
+# # X * A
+
+# node1 = helper.make_node(
+# "MatMul", [input_name, weight_name_a], ["X_times_A"], name="node1"
+# ) # X * A
+
+# # X * A + B
+
+# node2 = helper.make_node(
+# "Add", ["X_times_A", weight_name_b], [output_name], name="node2"
+# ) # X * A + B
+
+# # Define the tensors (values) in our graph
+# X_value_info = helper.make_tensor_value_info(
+# input_name, TensorProto.FLOAT, [None, 32]
+# )
+
+# output_value_info = helper.make_tensor_value_info(
+# output_name, TensorProto.FLOAT, [None, 32]
+# )
+
+# # Set A and B as parameters/weights
+# weights_a = np.random.randn(32, 32).astype(np.float32)
+
+# weights_b = np.random.randn(32, 32).astype(np.float32)
+
+# A_init = helper.make_tensor(
+# weight_name_a,
+# TensorProto.FLOAT,
+# [
+# 32,
+# 32,
+# ],
+# weights_a,
+# )
+# B_init = helper.make_tensor(
+# weight_name_b,
+# TensorProto.FLOAT,
+# [
+# 32,
+# 32,
+# ],
+# weights_b,
+# )
+
+# # Create the graph (model).
+# graph_def = helper.make_graph(
+# [node1, node2],
+# "simple_expression_model",
+# [X_value_info],
+# [output_value_info],
+# [A_init, B_init],
+# )
+
+# model_def = helper.make_model(graph_def, producer_name="onnx-simple-expression")
+
+# input_data = {"X": np.random.randn(1, 32).astype(np.float32)}
+
+# f = io.BytesIO()
+# onnx.save(model_def, f)
+
+# runtime_result = InferenceSession(f.getvalue()).run(None, input_data)
+
+# # rewrite the graph
+# new_model = engine.optimize(model=model_def)
+# assert new_model is not None
+
+# ggml_dummy_model = GgmlRuntimeBackend.prepare(new_model)
+# ggml_result = ggml_dummy_model.run(input_data)
+# assert np.allclose(ggml_result[0], runtime_result[0], rtol=1e-03, atol=1e-05)
+
+
+backend_test = onnx.backend.test.BackendTest(GgmlRuntimeBackend, __name__)
+
+backend_test.include("test_abs_")
+
+backend_test.include("test_add_")
+backend_test.exclude("test_add_uint8_") # not supported
+
+# backend_test.include("test_and_")
+
+# backend_test.include("test_argmax_")
+# backend_test.include("test_argmin_")
+
+# backend_test.include("test_operator_basic_")
+
+# backend_test.include("test_cast_")
+
+# backend_test.include("test_ceil_")
+
+# backend_test.include("test_concat_")
+# backend_test.include("test_operator_concat")
+
+backend_test.include("test_constant_")
+
+backend_test.include("test_constantofshape")
+
+# # backend_test.include("_conv_")
+# # backend_test.exclude("_deform_conv")
+# # backend_test.exclude("test_operator_conv")
+
+
+# # backend_test.include("_convtranspose_")
+# # backend_test.exclude("_deform_convtranspose")
+# # backend_test.exclude("test_operator_convtranspose")
+
+# backend_test.include("test_operator_chunk")
+
+# backend_test.include("test_depthtospace")
+
+# backend_test.include("test_div_")
+# backend_test.exclude("test_div_uint8_") # not supported
+
+# backend_test.include("test_elu_")
+# backend_test.include("test_ELU_")
+# backend_test.include("test_elu_example")
+
+# backend_test.include("test_eq_")
+
+# backend_test.include("test_equal_")
+# backend_test.exclude(".*equal.*.*string.*")
+
+# backend_test.include("test_exp_")
+# backend_test.include("test_operator_exp_")
+
+# backend_test.include("test_expand_")
+
+# backend_test.include("test_flatten_")
+# backend_test.include("test_operator_flatten_")
+
+
+# backend_test.include("test_floor_")
+
+# backend_test.include("test_greater_")
+
+# backend_test.include("test_gather_")
+# backend_test.exclude("test_gather_elements") # not supported
+
+# backend_test.include("test_gemm")
+# backend_test.exclude("test_gemm_default_scalar_bias")
+
+# backend_test.include("test_greater_")
+
+# backend_test.include("test_hardsigmoid_")
+
+# backend_test.include("test_hardmax_")
+
+# backend_test.include("test_identity_")
+# backend_test.exclude("test_identity_opt") # test case not correct: ONNX issue
+# backend_test.exclude("test_identity_sequence") # test case not correct: ONNX issue
+
+# backend_test.include("test_instancenorm")
+
+# # backend_test.include("test_leakyrelu")
+
+# backend_test.include("test_less_")
+
+backend_test.include("test_log_")
+
+# backend_test.include("test_LogSoftmax_")
+
+# backend_test.include("test_lrn")
+
+backend_test.include("test_matmul_")
+# backend_test.include("test_operator_mm")
+
+# backend_test.include("test_max_")
+# backend_test.exclude("test_max_float16") # not supported
+# backend_test.exclude("test_max_float64") # not supported
+# backend_test.exclude("test_max_int64") # not supported
+# backend_test.exclude("test_max_uint") # not supported
+# backend_test.include("test_operator_max_")
+
+
+# backend_test.include("test_mean_")
+
+# backend_test.include("test_min_")
+# backend_test.exclude("test_min_float16") # not supported
+# backend_test.exclude("test_min_float64") # not supported
+# backend_test.exclude("test_min_int64") # not supported
+# backend_test.exclude("test_min_uint") # not supported
+# backend_test.include("test_operator_min_")
+
+
+backend_test.include("test_mul_")
+backend_test.exclude("test_mul_uint8") # not supported
+
+backend_test.include("test_neg_")
+
+# backend_test.include("test_not_")
+
+# backend_test.include("test_or_")
+
+# backend_test.include("test_prelu")
+# backend_test.include("test_PRelu_")
+# backend_test.include("test_prelu_example")
+
+# backend_test.include("test_pow_")
+# backend_test.exclude("test_pow_bcast") # not supported
+# backend_test.exclude("test_pow_types_int64") # not supported
+# backend_test.include("test_operator_pow_")
+
+backend_test.include("test_range_")
+backend_test.exclude("test_range_float") # segfault
+backend_test.exclude("test_range_int32") # segfault
+
+# backend_test.include("test_reciprocal")
+
+# backend_test.include("test_reduce_max_")
+# backend_test.include("test_reduce_mean_")
+# backend_test.include("test_operator_reduced_mean_")
+# backend_test.include("test_reduce_min_")
+# backend_test.include("test_reduce_prod_")
+# backend_test.include("test_reduce_sum_")
+# backend_test.include("test_operator_reduced_sum_")
+# backend_test.include("test_reduce_log_sum_")
+# backend_test.exclude("test_reduce_log_sum_exp")
+
+
+# backend_test.include("test_reduce_l1_")
+# backend_test.include("test_reduce_l2_")
+
+# backend_test.include("test_relu_")
+# backend_test.include("test_relu_example")
+# backend_test.include("test_ReLU_")
+
+backend_test.include("test_reshape_")
+backend_test.exclude("test_reshape_allowzero") # not supported
+
+# backend_test.include("test_selu_")
+# backend_test.include("test_selu_example")
+# backend_test.include("test_SELU_")
+# backend_test.include("test_operator_selu_")
+
+backend_test.include("test_shape_")
+
+# backend_test.include("test_sigmoid_")
+# backend_test.include("test_Sigmoid_")
+
+backend_test.include("test_size_")
+
+# backend_test.include("test_slice_")
+
+# backend_test.include("test_softmax_")
+# backend_test.exclude("test_softmax_axis_0") # not supported
+# backend_test.exclude("test_softmax_axis_1") # not supported
+# backend_test.exclude("test_softmax_large_number") # not supported
+# backend_test.exclude("test_softmax_lastdim") # Out of tolerance
+# # backend_test.include("test_Softmax")
+
+# backend_test.include("test_softplus_")
+# backend_test.include("test_softsign_")
+# backend_test.include("test_Softplus")
+
+# backend_test.include("test_spacetodepth")
+
+# backend_test.include("test_split_")
+# backend_test.exclude(".*split.*.*to.*.*sequence.*")
+
+backend_test.include("test_sqrt_")
+backend_test.include("test_operator_sqrt_")
+
+backend_test.include("test_sub_")
+backend_test.exclude("test_sub_bcast_") # not supported
+backend_test.exclude("test_sub_uint8_") # not supported
+
+backend_test.include("test_sum_")
+
+# backend_test.include("test_tanh_")
+# backend_test.include("test_Tanh_")
+
+# backend_test.include("test_tile_")
+
+# backend_test.include("test_top_k")
+
+# backend_test.include("test_transpose_")
+
+backend_test.include("test_unsqueeze_")
+backend_test.exclude("test_unsqueeze_negative_axes") # 5D Array not supported
+backend_test.exclude("test_unsqueeze_three_axes") # 6D Array not supported
+backend_test.exclude("test_unsqueeze_two_axes") # 5D Array not supported
+backend_test.exclude("test_unsqueeze_unsorted_axes") # 5D Array not supported
+
+# backend_test.include("test_where_")
+# backend_test.exclude("test_where_long") # not supported
+
+# backend_test.include("test_xor_")
+
+# backend_test.exclude(".*FLOAT*E*M*.*")
+# backend_test.exclude(".*ver18.*")
+
+# This is a pytest magic variable to load extra plugins
+pytest_plugins = ("onnx.backend.test.report",)
+
+# import all test cases at global scope to make them visible to python.unittest
+globals().update(backend_test.enable_report().test_cases)