Author SHA1 Message Date
kromskii2 ee94d8e529 Воркед 2025-03-15 09:36:28 +07:00
kromskii2 ac32c55ab9 Добавлен новый интерфейс с навигационной панелью и страницами для управления моделями, настройками и генерацией изображений. Реализованы стили для новых компонентов и добавлены функции для загрузки шрифтов и иконок. Обновлен основной класс окна для поддержки новых страниц. 2025-03-15 09:10:31 +07:00
kromskii2 df447a1ecf Добавлено меню настроек с возможностью изменения API, интерфейса, генерации и горячих клавиш. Обновлен основной интерфейс с добавлением меню. Созданы диалоговые окна для настройки параметров. 2025-03-15 08:38:56 +07:00
kromskii2 01395a5aa4 Merge pull request #3 from kromskii2/feature/prompt-translations
Feature/prompt translations
2025-03-14 20:23:17 +07:00
kromskii2 74dd9824f3 Merge pull request #2 from kromskii2/interface
Обновлен интерфейс окон: изменены стили и размеры элементов, улучшена…
2025-03-14 20:22:49 +07:00
kromskii2 11d03556da Merge pull request #1 from kromskii2/feature/negative-prompts
Добавлено окно негативных промптов с категориями и автоматическим пер…
2025-03-14 20:22:25 +07:00
kromskii2 02c7b9483b Улучшен интерфейс менеджера пресетов размеров: добавлен фрейм для кнопок, изменены стили кнопок и заголовка, улучшено разделение пресетов на две группы. Изменены названия пресетов для упрощения. Добавлен метод создания кнопок с улучшенным дизайном. 2025-03-14 20:20:55 +07:00
kromskii2 828f3c6c12 Обновлен интерфейс окон: изменены стили и размеры элементов, улучшена читаемость текста, добавлены иконки для кнопок, оптимизированы отступы и размеры компонентов. 2025-03-14 20:11:38 +07:00
kromskii2 8e6e54c802 Добавлены новые бинарные файлы для кэширования модулей: negative_prompt_categories, negative_prompt_window, prompt_categories, prompt_translations, prompt_window, size_preset_manager и size_presets. 2025-03-14 20:05:25 +07:00
kromskii2 603f6827b6 Добавлены пресеты размеров изображения с красивыми кнопками 2025-03-14 20:03:37 +07:00
kromskii2 41999b31c1 Добавлена кнопка копирования изображения в буфер обмена 2025-03-14 19:59:11 +07:00
kromskii2 6e2defe3b6 Добавлены переводы промптов и изменен размер окна негативных промптов 2025-03-14 19:56:00 +07:00
1164 changed files with 57696 additions and 77922 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
SD_API_URL=http://localhost:7860
+3
View File
@@ -0,0 +1,3 @@
{
"python.pythonPath": "c:\\projects\\stable_api\\venv\\Scripts\\python.exe"
}
BIN
View File
Binary file not shown.
+126 -390
View File
@@ -2,22 +2,37 @@ import sys
import json import json
import base64 import base64
import requests import requests
import os
from time import sleep from time import sleep
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout, QLabel, QLineEdit, QPushButton,
QComboBox, QSpinBox, QDoubleSpinBox, QProgressBar, QComboBox, QSpinBox, QDoubleSpinBox, QProgressBar,
QScrollArea, QTextEdit, QFileDialog) QScrollArea, QTextEdit, QFileDialog, QMenuBar, QMenu)
from PyQt6.QtCore import Qt, QThread, pyqtSignal, QTimer from PyQt6.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt6.QtGui import QPixmap, QImage from PyQt6.QtGui import QPixmap, QImage, QAction, QFontDatabase, QFont
from PIL import Image from PIL import Image
from io import BytesIO from io import BytesIO
from pathlib import Path
from dotenv import load_dotenv
# Импортируем новые модули # Загружаем переменные окружения
load_dotenv()
# Импортируем модули
from modules.console_window import ConsoleWindow from modules.console_window import ConsoleWindow
from modules.model_manager import ModelManager from modules.model_manager import ModelManager
from modules.sampler_manager import SamplerManager from modules.sampler_manager import SamplerManager
from modules.prompt_window import PromptWindow from modules.prompt_window import PromptWindow
from modules.negative_prompt_window import NegativePromptWindow from modules.negative_prompt_window import NegativePromptWindow
from modules.size_preset_manager import SizePresetManager
from modules.settings_menu import SettingsMenu
from modules.styles.base_window import BaseWindow
from modules.styles.navigation import NavigationPanel
from modules.styles.page import PageContainer
from modules.pages.home_page import HomePage
from modules.pages.models_page import ModelsPage
from modules.pages.settings_page import SettingsPage
from scripts.download_resources import download_font
class GenerationThread(QThread): class GenerationThread(QThread):
progress_updated = pyqtSignal(float, str) progress_updated = pyqtSignal(float, str)
@@ -59,427 +74,148 @@ class GenerationThread(QThread):
def stop(self): def stop(self):
self.is_generating = False self.is_generating = False
class MainWindow(QMainWindow): class MainWindow(BaseWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.api_url = "http://localhost:7860" # URL по умолчанию
self.console_window = None
self.prompt_window = None
self.negative_prompt_window = None
self.progress_timer = None
self.init_ui()
def init_ui(self):
self.setWindowTitle("Stable Diffusion UI") self.setWindowTitle("Stable Diffusion UI")
self.setStyleSheet(""" self.setMinimumSize(1200, 800)
QMainWindow {
background-color: #2b2b2b; # Получаем URL API из переменных окружения
} self.api_url = os.getenv('SD_API_URL', 'http://localhost:3000')
QWidget {
color: #ffffff; # Инициализируем менеджеры
font-size: 14px; self.model_manager = ModelManager(api_url=self.api_url)
} self.sampler_manager = SamplerManager(api_url=self.api_url)
QLineEdit, QTextEdit, QComboBox, QSpinBox, QDoubleSpinBox { self.size_preset_manager = SizePresetManager()
background-color: #3b3b3b;
border: 1px solid #555555; # Инициализируем окна
border-radius: 4px; self.prompt_window = PromptWindow()
padding: 5px; self.negative_prompt_window = NegativePromptWindow()
color: #ffffff; self.console_window = ConsoleWindow()
min-width: 100px;
} self.setup_ui()
QSpinBox::up-button, QDoubleSpinBox::up-button {
background-color: #4a4a4a; def setup_ui(self):
border: none; # Загружаем шрифт
border-left: 1px solid #555555; font_path = Path("resources/fonts/InterVariable.ttf")
border-bottom: 1px solid #555555; if not font_path.exists():
border-top-right-radius: 4px; download_font()
width: 20px; font_id = QFontDatabase.addApplicationFont(str(font_path))
height: 12px; if font_id != -1:
} font_family = QFontDatabase.applicationFontFamilies(font_id)[0]
QSpinBox::down-button, QDoubleSpinBox::down-button { app_font = QFont(font_family)
background-color: #4a4a4a; QApplication.setFont(app_font)
border: none;
border-left: 1px solid #555555;
border-bottom-right-radius: 4px;
width: 20px;
height: 12px;
}
QSpinBox::up-button:hover, QDoubleSpinBox::up-button:hover,
QSpinBox::down-button:hover, QDoubleSpinBox::down-button:hover {
background-color: #5a5a5a;
}
QSpinBox::up-button:pressed, QDoubleSpinBox::up-button:pressed,
QSpinBox::down-button:pressed, QDoubleSpinBox::down-button:pressed {
background-color: #666666;
}
QSpinBox::up-arrow, QDoubleSpinBox::up-arrow {
image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOCA0TDQgOEgxMkw4IDRaIiBmaWxsPSIjZmZmZmZmIi8+PC9zdmc+);
width: 12px;
height: 6px;
}
QSpinBox::down-arrow, QDoubleSpinBox::down-arrow {
image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOCAxMkwxMiA4SDRMOCAxMloiIGZpbGw9IiNmZmZmZmYiLz48L3N2Zz4=);
width: 12px;
height: 6px;
}
QPushButton {
background-color: #0d6efd;
border: none;
border-radius: 4px;
padding: 8px 16px;
color: white;
font-weight: bold;
}
QPushButton:hover {
background-color: #0b5ed7;
}
QPushButton:pressed {
background-color: #0a58ca;
}
QProgressBar {
border: 1px solid #555555;
border-radius: 4px;
text-align: center;
}
QProgressBar::chunk {
background-color: #0d6efd;
}
""")
# Создаем центральный виджет # Создаем центральный виджет
central_widget = QWidget() central_widget = QWidget()
self.setCentralWidget(central_widget) self.setCentralWidget(central_widget)
main_layout = QHBoxLayout(central_widget) main_layout = QVBoxLayout(central_widget)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# Левая панель с настройками # Создаем верхнюю панель
settings_widget = QWidget() top_panel = QHBoxLayout()
settings_layout = QVBoxLayout(settings_widget)
settings_layout.setSpacing(10)
# URL API # Кнопки для окон промптов
api_layout = QHBoxLayout() prompt_btn = QPushButton("Библиотека промптов")
api_label = QLabel("API URL:") prompt_btn.clicked.connect(self.show_prompt_window)
self.api_url_input = QLineEdit(self.api_url) top_panel.addWidget(prompt_btn)
self.api_url_input.textChanged.connect(self.update_api_url)
api_layout.addWidget(api_label)
api_layout.addWidget(self.api_url_input)
settings_layout.addLayout(api_layout)
# Промпт negative_prompt_btn = QPushButton("Негативные промпты")
prompt_layout = QVBoxLayout() negative_prompt_btn.clicked.connect(self.show_negative_prompt_window)
prompt_header = QHBoxLayout() top_panel.addWidget(negative_prompt_btn)
prompt_label = QLabel("Промпт:")
self.prompt_input = QTextEdit()
self.prompt_input.setMinimumHeight(100)
prompt_buttons = QHBoxLayout()
self.prompt_button = QPushButton("Готовые промпты")
self.prompt_button.clicked.connect(self.toggle_prompt_window)
self.negative_prompt_button = QPushButton("Негативные промпты")
self.negative_prompt_button.clicked.connect(self.toggle_negative_prompt_window)
prompt_buttons.addWidget(self.prompt_button)
prompt_buttons.addWidget(self.negative_prompt_button)
prompt_header.addWidget(prompt_label)
prompt_header.addLayout(prompt_buttons)
prompt_layout.addLayout(prompt_header)
prompt_layout.addWidget(self.prompt_input)
settings_layout.addLayout(prompt_layout)
# Негативный промпт # Пресеты разрешения
negative_prompt_layout = QVBoxLayout() resolution_combo = QComboBox()
negative_prompt_label = QLabel("Негативный промпт:") resolution_combo.addItems(self.size_preset_manager.get_preset_names())
self.negative_prompt_input = QTextEdit() resolution_combo.currentTextChanged.connect(self.on_resolution_changed)
self.negative_prompt_input.setMinimumHeight(100) top_panel.addWidget(resolution_combo)
negative_prompt_layout.addWidget(negative_prompt_label)
negative_prompt_layout.addWidget(self.negative_prompt_input)
settings_layout.addLayout(negative_prompt_layout)
# Добавляем менеджер моделей # Кнопка консоли
self.model_manager = ModelManager(self.api_url) console_btn = QPushButton("Консоль")
self.model_manager.model_changed.connect(self.on_model_changed) console_btn.clicked.connect(self.show_console)
settings_layout.addWidget(self.model_manager) top_panel.addWidget(console_btn)
# Добавляем менеджер сэмплеров top_panel.addStretch()
self.sampler_manager = SamplerManager(self.api_url) main_layout.addLayout(top_panel)
settings_layout.addWidget(self.sampler_manager)
# Параметры генерации # Создаем горизонтальный layout для навигации и контента
params_layout = QVBoxLayout() content_layout = QHBoxLayout()
# Размеры # Добавляем навигационную панель
size_layout = QHBoxLayout() self.nav_panel = NavigationPanel()
width_label = QLabel("Ширина:") content_layout.addWidget(self.nav_panel)
self.width_input = QSpinBox()
self.width_input.setRange(64, 2048)
self.width_input.setValue(512)
height_label = QLabel("Высота:")
self.height_input = QSpinBox()
self.height_input.setRange(64, 2048)
self.height_input.setValue(512)
size_layout.addWidget(width_label)
size_layout.addWidget(self.width_input)
size_layout.addWidget(height_label)
size_layout.addWidget(self.height_input)
params_layout.addLayout(size_layout)
# Сид # Создаем контейнер для страниц
seed_layout = QHBoxLayout() self.page_container = PageContainer()
seed_label = QLabel("Сид:") content_layout.addWidget(self.page_container)
self.seed_input = QSpinBox()
self.seed_input.setRange(-1, 999999999)
self.seed_input.setValue(-1)
seed_layout.addWidget(seed_label)
seed_layout.addWidget(self.seed_input)
params_layout.addLayout(seed_layout)
# CFG Scale main_layout.addLayout(content_layout)
cfg_layout = QHBoxLayout()
cfg_label = QLabel("CFG Scale:")
self.cfg_input = QDoubleSpinBox()
self.cfg_input.setRange(1.0, 30.0)
self.cfg_input.setValue(7.0)
cfg_layout.addWidget(cfg_label)
cfg_layout.addWidget(self.cfg_input)
params_layout.addLayout(cfg_layout)
# Шаги # Добавляем страницы
steps_layout = QHBoxLayout() self.home_page = HomePage(
steps_label = QLabel("Шаги:") model_manager=self.model_manager,
self.steps_input = QSpinBox() sampler_manager=self.sampler_manager,
self.steps_input.setRange(1, 150) size_preset_manager=self.size_preset_manager
self.steps_input.setValue(20) )
steps_layout.addWidget(steps_label) self.models_page = ModelsPage(self.model_manager)
steps_layout.addWidget(self.steps_input) self.settings_page = SettingsPage()
params_layout.addLayout(steps_layout)
settings_layout.addLayout(params_layout) self.page_container.add_page("home", self.home_page)
self.page_container.add_page("models", self.models_page)
self.page_container.add_page("settings", self.settings_page)
# Добавляем кнопку консоли # Подключаем сигнал смены страницы
self.console_button = QPushButton("Открыть консоль") self.nav_panel.page_changed.connect(self.switch_page)
self.console_button.clicked.connect(self.toggle_console)
settings_layout.addWidget(self.console_button)
# Кнопка генерации # Показываем домашнюю страницу по умолчанию
self.generate_button = QPushButton("Сгенерировать") self.page_container.show_page("home")
self.generate_button.clicked.connect(self.start_generation)
settings_layout.addWidget(self.generate_button)
# Прогресс бар # Загружаем данные
self.progress_bar = QProgressBar() self.load_data()
settings_layout.addWidget(self.progress_bar)
# Добавляем левую панель в основной layout def load_data(self):
main_layout.addWidget(settings_widget, stretch=1) """Загрузка данных с сервера"""
# Правая панель для результатов
results_widget = QWidget()
results_layout = QVBoxLayout(results_widget)
# Область для отображения изображений
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setMinimumWidth(512)
self.results_content = QWidget()
self.results_content_layout = QVBoxLayout(self.results_content)
scroll_area.setWidget(self.results_content)
results_layout.addWidget(scroll_area)
# Добавляем правую панель в основной layout
main_layout.addWidget(results_widget, stretch=2)
# Устанавливаем размер окна
self.setMinimumSize(1200, 800)
def toggle_console(self):
"""Открыть/закрыть окно консоли"""
if self.console_window is None:
self.console_window = ConsoleWindow(parent=self)
self.console_window.console_closed.connect(self.on_console_closed)
self.console_window.show()
else:
self.console_window.close()
def on_console_closed(self):
"""Обработчик закрытия окна консоли"""
self.console_window = None
def on_model_changed(self, model_name):
"""Обработчик смены модели"""
print(f"Модель изменена на: {model_name}")
def log_to_console(self, message):
"""Логирование в консоль"""
if self.console_window:
self.console_window.log(message)
print(message)
def toggle_prompt_window(self):
"""Открыть/закрыть окно с промптами"""
if self.prompt_window is None:
self.prompt_window = PromptWindow(parent=self)
self.prompt_window.prompt_selected.connect(self.add_prompt)
self.prompt_window.show()
else:
self.prompt_window.close()
def toggle_negative_prompt_window(self):
"""Открыть/закрыть окно с негативными промптами"""
if self.negative_prompt_window is None:
self.negative_prompt_window = NegativePromptWindow(parent=self)
self.negative_prompt_window.prompt_selected.connect(self.add_negative_prompt)
self.negative_prompt_window.show()
else:
self.negative_prompt_window.close()
def add_prompt(self, text):
"""Добавить промпт в поле ввода"""
current_text = self.prompt_input.toPlainText()
if current_text:
current_text += ", "
self.prompt_input.setText(current_text + text)
def add_negative_prompt(self, text):
"""Добавить негативный промпт в поле ввода"""
current_text = self.negative_prompt_input.toPlainText()
if current_text:
current_text += ", "
self.negative_prompt_input.setText(current_text + text)
def start_generation(self):
self.generate_button.setEnabled(False)
self.progress_bar.setValue(0)
params = {
"prompt": self.prompt_input.toPlainText(),
"negative_prompt": self.negative_prompt_input.toPlainText(),
"width": self.width_input.value(),
"height": self.height_input.value(),
"seed": self.seed_input.value(),
"cfg_scale": self.cfg_input.value(),
"steps": self.steps_input.value(),
"sampler_name": self.sampler_manager.get_current_sampler(),
"batch_size": 1
}
self.log_to_console(f"Начало генерации с параметрами: {json.dumps(params, indent=2, ensure_ascii=False)}")
# Запускаем таймер для отслеживания прогресса
self.progress_timer = QTimer()
self.progress_timer.timeout.connect(self.check_progress)
self.progress_timer.start(100) # Проверяем каждые 100 мс
self.generation_thread = GenerationThread(self.api_url_input.text(), params)
self.generation_thread.generation_complete.connect(self.handle_generation_complete)
self.generation_thread.error_occurred.connect(self.handle_error)
self.generation_thread.start()
def check_progress(self):
"""Проверка прогресса генерации"""
try: try:
response = requests.get(f"{self.api_url_input.text()}/sdapi/v1/progress") # Загружаем список моделей
if response.status_code == 200: self.model_manager.load_models()
data = response.json()
progress = data.get('progress', 0)
current_step = data.get('current_step', 0)
total_steps = data.get('total_steps', 1)
percentage = int(progress * 100) # Загружаем список сэмплеров
self.progress_bar.setValue(percentage) self.sampler_manager.load_samplers()
self.log_to_console(f"Прогресс: {percentage}% - Шаг {current_step}/{total_steps}")
# Обновляем интерфейс
self.home_page.update_ui()
self.models_page.update_ui()
# Если генерация завершена, останавливаем таймер
if progress >= 1.0:
self.progress_timer.stop()
self.progress_timer = None
except Exception as e: except Exception as e:
print(f"Ошибка при получении прогресса: {str(e)}") self.console_window.log(f"Ошибка загрузки данных: {str(e)}", "ERROR")
def handle_generation_complete(self, images): def show_prompt_window(self):
"""Обработка завершения генерации""" """Показать окно промптов"""
# Останавливаем таймер, если он ещё активен self.prompt_window.show()
if self.progress_timer:
self.progress_timer.stop()
self.progress_timer = None
self.generate_button.setEnabled(True) def show_negative_prompt_window(self):
self.progress_bar.setValue(100) """Показать окно негативных промптов"""
self.log_to_console("Генерация завершена успешно") self.negative_prompt_window.show()
# Очищаем предыдущие результаты def show_console(self):
for i in reversed(range(self.results_content_layout.count())): """Показать консоль"""
self.results_content_layout.itemAt(i).widget().setParent(None) self.console_window.show()
for img_data in images: def on_resolution_changed(self, preset_name: str):
try: """Обработка изменения пресета разрешения"""
# Декодируем base64 в байты preset = self.size_preset_manager.get_preset(preset_name)
img_bytes = base64.b64decode(img_data) if preset:
self.log_to_console(f"Размер полученных данных: {len(img_bytes)} байт") self.home_page.set_resolution(preset.width, preset.height)
# Создаем объект изображения def switch_page(self, page_name):
img = Image.open(BytesIO(img_bytes)) self.page_container.show_page(page_name)
self.log_to_console(f"Размер изображения: {img.size}, формат: {img.format}")
# Конвертируем в RGB если нужно def main():
if img.mode != 'RGB':
img = img.convert('RGB')
# Сохраняем во временный буфер как PNG
buffer = BytesIO()
img.save(buffer, format='PNG')
buffer.seek(0)
# Создаем QPixmap
pixmap = QPixmap()
if not pixmap.loadFromData(buffer.getvalue()):
raise Exception("Не удалось создать QPixmap из данных")
# Проверяем размер QPixmap
if pixmap.isNull():
raise Exception("Создан пустой QPixmap")
self.log_to_console(f"Размер QPixmap: {pixmap.width()}x{pixmap.height()}")
# Создаем и добавляем QLabel с изображением
img_label = QLabel()
img_label.setPixmap(pixmap)
img_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
# Создаем кнопку сохранения
save_button = QPushButton("Сохранить")
save_button.clicked.connect(lambda checked, img=img: self.save_image(img))
# Создаем контейнер для изображения и кнопки
container = QWidget()
container_layout = QVBoxLayout(container)
container_layout.addWidget(img_label)
container_layout.addWidget(save_button)
self.results_content_layout.addWidget(container)
self.log_to_console("Изображение успешно добавлено в интерфейс")
except Exception as e:
error_msg = f"Ошибка отображения изображения: {str(e)}"
self.log_to_console(error_msg)
error_label = QLabel(error_msg)
self.results_content_layout.addWidget(error_label)
def handle_error(self, error_message):
"""Обработка ошибок"""
self.generate_button.setEnabled(True)
self.log_to_console(f"Ошибка: {error_message}")
def save_image(self, img):
file_path, _ = QFileDialog.getSaveFileName(self, "Сохранить изображение", "", "PNG Files (*.png);;JPEG Files (*.jpg)")
if file_path:
img.save(file_path)
def update_api_url(self):
"""Обновление URL API во всех компонентах"""
new_url = self.api_url_input.text()
self.model_manager.update_api_url(new_url)
self.sampler_manager.update_api_url(new_url)
self.log_to_console(f"API URL обновлен: {new_url}")
if __name__ == '__main__':
app = QApplication(sys.argv) app = QApplication(sys.argv)
window = MainWindow() window = MainWindow()
window.show() window.show()
sys.exit(app.exec()) sys.exit(app.exec())
if __name__ == "__main__":
main()
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+26 -19
View File
@@ -17,36 +17,42 @@ class ConsoleWindow(QDialog):
def setup_ui(self): def setup_ui(self):
self.setStyleSheet(""" self.setStyleSheet("""
QDialog { QDialog {
background-color: #2b2b2b; background-color: #1e1e1e;
min-width: 600px; min-width: 700px;
min-height: 400px; min-height: 500px;
} }
QTextEdit { QTextEdit {
background-color: #1e1e1e; background-color: #252526;
color: #ffffff; color: #d4d4d4;
border: 1px solid #3b3b3b; border: none;
border-radius: 4px; border-radius: 8px;
font-family: 'Consolas', 'Courier New', monospace; font-family: 'JetBrains Mono', 'Consolas', 'Courier New', monospace;
font-size: 12px; font-size: 13px;
padding: 8px; padding: 12px;
selection-background-color: #264f78;
} }
QPushButton { QPushButton {
background-color: #0d6efd; background-color: #2d2d2d;
color: white; color: #d4d4d4;
border: none; border: 1px solid #3e3e3e;
border-radius: 4px; border-radius: 6px;
padding: 8px 16px; padding: 8px 16px;
font-weight: bold; font-weight: 500;
min-width: 100px;
margin: 4px;
} }
QPushButton:hover { QPushButton:hover {
background-color: #0b5ed7; background-color: #3e3e3e;
border-color: #565656;
} }
QPushButton:pressed { QPushButton:pressed {
background-color: #0a58ca; background-color: #565656;
} }
""") """)
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.setContentsMargins(16, 16, 16, 16)
layout.setSpacing(12)
# Область для логов # Область для логов
self.console_output = QTextEdit() self.console_output = QTextEdit()
@@ -55,11 +61,12 @@ class ConsoleWindow(QDialog):
# Кнопки управления # Кнопки управления
buttons_layout = QHBoxLayout() buttons_layout = QHBoxLayout()
buttons_layout.setSpacing(8)
copy_button = QPushButton("Копировать всё") copy_button = QPushButton("📋 Копировать")
copy_button.clicked.connect(self.copy_all) copy_button.clicked.connect(self.copy_all)
clear_button = QPushButton("Очистить") clear_button = QPushButton("🗑️ Очистить")
clear_button.clicked.connect(self.clear_console) clear_button.clicked.connect(self.clear_console)
buttons_layout.addWidget(copy_button) buttons_layout.addWidget(copy_button)
@@ -0,0 +1,71 @@
from enum import Enum, auto
from typing import List, Dict
class NegativePromptCategory(Enum):
"""Категории негативных промптов"""
QUALITY = auto()
ARTIFACTS = auto()
COMPOSITION = auto()
ANATOMY = auto()
STYLE = auto()
class NegativePromptData:
"""Класс для хранения данных о негативном промпте"""
def __init__(self, text: str, description: str = "", weight: float = 1.0):
self.text = text
self.description = description
self.weight = weight
class NegativePromptCategories:
"""Класс для работы с категориями негативных промптов"""
@staticmethod
def get_prompts() -> Dict[NegativePromptCategory, List[NegativePromptData]]:
"""Возвращает словарь с негативными промптами по категориям"""
return {
NegativePromptCategory.QUALITY: [
NegativePromptData("low quality", "Низкое качество"),
NegativePromptData("blurry", "Размытое изображение"),
NegativePromptData("pixelated", "Пикселизация"),
NegativePromptData("jpeg artifacts", "JPEG артефакты"),
NegativePromptData("compression artifacts", "Артефакты сжатия"),
],
NegativePromptCategory.ARTIFACTS: [
NegativePromptData("watermark", "Водяные знаки"),
NegativePromptData("signature", "Подписи"),
NegativePromptData("text", "Текст на изображении"),
NegativePromptData("frame", "Рамки"),
NegativePromptData("duplicate", "Дубликаты элементов"),
],
NegativePromptCategory.COMPOSITION: [
NegativePromptData("bad composition", "Плохая композиция"),
NegativePromptData("unbalanced", "Несбалансированная композиция"),
NegativePromptData("cropped", "Обрезанное изображение"),
NegativePromptData("out of frame", "Выход за пределы кадра"),
],
NegativePromptCategory.ANATOMY: [
NegativePromptData("bad anatomy", "Неправильная анатомия"),
NegativePromptData("extra limbs", "Лишние конечности"),
NegativePromptData("missing limbs", "Отсутствующие конечности"),
NegativePromptData("deformed", "Деформации"),
NegativePromptData("mutated", "Мутации"),
],
NegativePromptCategory.STYLE: [
NegativePromptData("3d render", "3D рендер"),
NegativePromptData("cartoon", "Мультяшный стиль"),
NegativePromptData("painting", "Живопись"),
NegativePromptData("sketch", "Набросок"),
NegativePromptData("anime", "Аниме"),
],
}
@staticmethod
def get_category_name(category: NegativePromptCategory) -> str:
"""Возвращает название категории на русском"""
return {
NegativePromptCategory.QUALITY: "Качество",
NegativePromptCategory.ARTIFACTS: "Артефакты",
NegativePromptCategory.COMPOSITION: "Композиция",
NegativePromptCategory.ANATOMY: "Анатомия",
NegativePromptCategory.STYLE: "Стиль",
}[category]
+86
View File
@@ -0,0 +1,86 @@
from enum import Enum, auto
from typing import List, Dict
class PromptCategory(Enum):
"""Категории промптов"""
STYLE = auto()
LIGHTING = auto()
COMPOSITION = auto()
CAMERA = auto()
COLORS = auto()
MOOD = auto()
QUALITY = auto()
class PromptData:
"""Класс для хранения данных о промпте"""
def __init__(self, text: str, description: str = "", weight: float = 1.0):
self.text = text
self.description = description
self.weight = weight
class PromptCategories:
"""Класс для работы с категориями промптов"""
@staticmethod
def get_prompts() -> Dict[PromptCategory, List[PromptData]]:
"""Возвращает словарь с промптами по категориям"""
return {
PromptCategory.STYLE: [
PromptData("digital art", "Цифровое искусство"),
PromptData("oil painting", "Масляная живопись"),
PromptData("watercolor", "Акварель"),
PromptData("pencil sketch", "Карандашный набросок"),
PromptData("anime style", "Аниме стиль"),
PromptData("photorealistic", "Фотореалистичный"),
],
PromptCategory.LIGHTING: [
PromptData("soft lighting", "Мягкое освещение"),
PromptData("dramatic lighting", "Драматическое освещение"),
PromptData("cinematic lighting", "Кинематографическое освещение"),
PromptData("natural light", "Естественное освещение"),
PromptData("studio lighting", "Студийное освещение"),
],
PromptCategory.COMPOSITION: [
PromptData("rule of thirds", "Правило третей"),
PromptData("symmetrical", "Симметричная композиция"),
PromptData("centered composition", "Центральная композиция"),
PromptData("dynamic pose", "Динамичная поза"),
],
PromptCategory.CAMERA: [
PromptData("close-up shot", "Крупный план"),
PromptData("wide angle", "Широкий угол"),
PromptData("bokeh", "Боке"),
PromptData("depth of field", "Глубина резкости"),
],
PromptCategory.COLORS: [
PromptData("vibrant colors", "Яркие цвета"),
PromptData("pastel colors", "Пастельные цвета"),
PromptData("monochrome", "Монохром"),
PromptData("high contrast", "Высокий контраст"),
],
PromptCategory.MOOD: [
PromptData("peaceful", "Умиротворенное"),
PromptData("mysterious", "Таинственное"),
PromptData("energetic", "Энергичное"),
PromptData("melancholic", "Меланхоличное"),
],
PromptCategory.QUALITY: [
PromptData("highly detailed", "Высокая детализация"),
PromptData("8k uhd", "Высокое разрешение"),
PromptData("masterpiece", "Шедевр"),
PromptData("best quality", "Лучшее качество"),
],
}
@staticmethod
def get_category_name(category: PromptCategory) -> str:
"""Возвращает название категории на русском"""
return {
PromptCategory.STYLE: "Стили",
PromptCategory.LIGHTING: "Освещение",
PromptCategory.COMPOSITION: "Композиция",
PromptCategory.CAMERA: "Камера",
PromptCategory.COLORS: "Цвета",
PromptCategory.MOOD: "Настроение",
PromptCategory.QUALITY: "Качество",
}[category]
+86
View File
@@ -0,0 +1,86 @@
from typing import Dict
class PromptTranslations:
"""Класс для работы с переводами промптов"""
@staticmethod
def get_translations() -> Dict[str, str]:
"""Возвращает словарь с переводами промптов"""
return {
# Стили
"digital art": "цифровое искусство",
"oil painting": "масляная живопись",
"watercolor": "акварель",
"pencil sketch": "карандашный набросок",
"anime style": "аниме стиль",
"photorealistic": "фотореалистичный",
# Освещение
"soft lighting": "мягкое освещение",
"dramatic lighting": "драматическое освещение",
"cinematic lighting": "кинематографическое освещение",
"natural light": "естественное освещение",
"studio lighting": "студийное освещение",
# Композиция
"rule of thirds": "правило третей",
"symmetrical": "симметричный",
"centered composition": "центральная композиция",
"dynamic pose": "динамичная поза",
# Камера
"close-up shot": "крупный план",
"wide angle": "широкий угол",
"bokeh": "боке",
"depth of field": "глубина резкости",
# Цвета
"vibrant colors": "яркие цвета",
"pastel colors": "пастельные цвета",
"monochrome": "монохром",
"high contrast": "высокий контраст",
# Настроение
"peaceful": "умиротворенный",
"mysterious": "таинственный",
"energetic": "энергичный",
"melancholic": "меланхоличный",
# Качество
"highly detailed": "высокая детализация",
"8k uhd": "8k uhd",
"masterpiece": "шедевр",
"best quality": "лучшее качество",
# Негативные промпты
"low quality": "низкое качество",
"blurry": "размытый",
"pixelated": "пикселизированный",
"jpeg artifacts": "jpeg артефакты",
"compression artifacts": "артефакты сжатия",
"watermark": "водяной знак",
"signature": "подпись",
"text": "текст",
"frame": "рамка",
"duplicate": "дубликат",
"bad composition": "плохая композиция",
"unbalanced": "несбалансированный",
"cropped": "обрезанный",
"out of frame": "за пределами кадра",
"bad anatomy": "плохая анатомия",
"extra limbs": "лишние конечности",
"missing limbs": "отсутствующие конечности",
"deformed": "деформированный",
"mutated": "мутированный",
"3d render": "3d рендер",
"cartoon": "мультяшный",
"painting": "живопись",
"sketch": "набросок",
"anime": "аниме",
}
@staticmethod
def translate(text: str) -> str:
"""Переводит промпт на русский язык"""
translations = PromptTranslations.get_translations()
return translations.get(text.lower(), text)
+141 -16
View File
@@ -2,6 +2,17 @@ from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QComboBox, QPushButton, QLabel) QComboBox, QPushButton, QLabel)
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
import requests import requests
from typing import List, Dict
import os
from dotenv import load_dotenv
# Загружаем переменные окружения
load_dotenv()
class Model:
def __init__(self, name: str, title: str = None):
self.name = name
self.title = title or name
class ModelManager(QWidget): class ModelManager(QWidget):
model_changed = pyqtSignal(str) model_changed = pyqtSignal(str)
@@ -9,12 +20,71 @@ class ModelManager(QWidget):
def __init__(self, api_url, parent=None): def __init__(self, api_url, parent=None):
super().__init__(parent) super().__init__(parent)
self.api_url = api_url self.api_url = api_url
self.models = []
self.current_model = None
self.setup_ui() self.setup_ui()
self.load_models() self.load_models()
def setup_ui(self): def setup_ui(self):
self.setStyleSheet("""
QWidget {
background-color: transparent;
}
QLabel {
color: #d4d4d4;
font-size: 13px;
font-weight: 500;
margin-right: 8px;
}
QComboBox {
background-color: #252526;
color: #d4d4d4;
border: 1px solid #3e3e3e;
border-radius: 6px;
padding: 6px 12px;
min-width: 200px;
font-size: 13px;
}
QComboBox:hover {
border-color: #565656;
}
QComboBox:focus {
border-color: #007acc;
}
QComboBox::drop-down {
border: none;
width: 20px;
}
QComboBox::down-arrow {
image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTggMTFMNCBTTDEyIDUiIHN0cm9rZT0iI2Q0ZDRkNCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+);
}
QComboBox QAbstractItemView {
background-color: #252526;
color: #d4d4d4;
border: 1px solid #3e3e3e;
selection-background-color: #094771;
outline: none;
}
QPushButton {
background-color: #2d2d2d;
color: #d4d4d4;
border: 1px solid #3e3e3e;
border-radius: 6px;
padding: 6px 12px;
font-size: 13px;
}
QPushButton:hover {
background-color: #3e3e3e;
border-color: #565656;
}
QPushButton:pressed {
background-color: #565656;
}
""")
layout = QHBoxLayout(self) layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(8)
# Метка # Метка
label = QLabel("Модель:") label = QLabel("Модель:")
@@ -22,11 +92,13 @@ class ModelManager(QWidget):
# Выпадающий список моделей # Выпадающий список моделей
self.model_combo = QComboBox() self.model_combo = QComboBox()
self.model_combo.setFixedHeight(32)
self.model_combo.currentTextChanged.connect(self.on_model_changed) self.model_combo.currentTextChanged.connect(self.on_model_changed)
layout.addWidget(self.model_combo) layout.addWidget(self.model_combo)
# Кнопка обновления # Кнопка обновления
refresh_button = QPushButton("🔄") refresh_button = QPushButton("🔄")
refresh_button.setFixedSize(32, 32)
refresh_button.setToolTip("Обновить список моделей") refresh_button.setToolTip("Обновить список моделей")
refresh_button.clicked.connect(self.load_models) refresh_button.clicked.connect(self.load_models)
layout.addWidget(refresh_button) layout.addWidget(refresh_button)
@@ -38,33 +110,86 @@ class ModelManager(QWidget):
try: try:
response = requests.get(f"{self.api_url}/sdapi/v1/sd-models") response = requests.get(f"{self.api_url}/sdapi/v1/sd-models")
if response.status_code == 200: if response.status_code == 200:
models = response.json() models_data = response.json()
current_model = self.model_combo.currentText() self.models = [
Model(model.get('title', ''), model.get('model_name', ''))
for model in models_data
]
# Получаем текущую модель
options_response = requests.get(f"{self.api_url}/sdapi/v1/options")
if options_response.status_code == 200:
current_model_name = options_response.json().get('sd_model_checkpoint')
self.current_model = next(
(model for model in self.models if model.name == current_model_name),
self.models[0] if self.models else None
)
# Обновляем UI
self.model_combo.clear() self.model_combo.clear()
for model in models: for model in self.models:
self.model_combo.addItem(model.get('title', '')) self.model_combo.addItem(model.title)
# Устанавливаем текущую модель
if self.current_model:
index = self.model_combo.findText(self.current_model.title)
if index >= 0:
self.model_combo.setCurrentIndex(index)
# Восстанавливаем выбранную модель, если она всё ещё доступна
index = self.model_combo.findText(current_model)
if index >= 0:
self.model_combo.setCurrentIndex(index)
except Exception as e: except Exception as e:
print(f"Ошибка при загрузке моделей: {str(e)}") print(f"Ошибка при загрузке моделей: {str(e)}")
self.models = []
self.current_model = None
def on_model_changed(self, model_name): def on_model_changed(self, model_title):
"""Обработка смены модели""" """Обработка смены модели"""
model = next(
(m for m in self.models if m.title == model_title),
None
)
if model:
try:
response = requests.post(
f"{self.api_url}/sdapi/v1/options",
json={"sd_model_checkpoint": model.name}
)
if response.status_code == 200:
self.current_model = model
self.model_changed.emit(model.name)
except Exception as e:
print(f"Ошибка при смене модели: {str(e)}")
def update_api_url(self, new_url):
"""Обновить URL API"""
self.api_url = new_url
self.load_models()
def get_models(self):
"""Возвращает список доступных моделей"""
return self.models
def get_model_names(self):
"""Возвращает список имен моделей"""
return [model.name for model in self.models]
def get_current_model(self):
"""Возвращает текущую модель"""
return self.current_model
def switch_model(self, model_name: str) -> bool:
"""Переключение на другую модель"""
try: try:
response = requests.post( response = requests.post(
f"{self.api_url}/sdapi/v1/options", f"{self.api_url}/sdapi/v1/options",
json={"sd_model_checkpoint": model_name} json={"sd_model_checkpoint": model_name}
) )
if response.status_code == 200: if response.status_code == 200:
self.model_changed.emit(model_name) self.current_model = next(
(model for model in self.models if model.name == model_name),
None
)
return True
return False
except Exception as e: except Exception as e:
print(f"Ошибка при смене модели: {str(e)}") print(f"Ошибка переключения модели: {str(e)}")
return False
def update_api_url(self, new_url):
"""Обновить URL API"""
self.api_url = new_url
self.load_models()
+2 -2
View File
@@ -18,8 +18,8 @@ class NegativePromptWindow(QDialog):
self.setStyleSheet(""" self.setStyleSheet("""
QDialog { QDialog {
background-color: #2b2b2b; background-color: #2b2b2b;
min-width: 1500px; min-width: 1700px;
min-height: 700px; min-height: 800px;
} }
QScrollArea { QScrollArea {
background-color: #1e1e1e; background-color: #1e1e1e;
Binary file not shown.
+237
View File
@@ -0,0 +1,237 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QSpinBox,
QComboBox, QProgressBar)
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QPixmap
import requests
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
from ..styles.page import BasePage
class HomePage(BasePage):
def __init__(self, model_manager, sampler_manager, size_preset_manager, parent=None):
super().__init__(parent)
self.model_manager = model_manager
self.sampler_manager = sampler_manager
self.size_preset_manager = size_preset_manager
self.icon_manager = IconManager.get_instance()
self.setup_ui()
def setup_ui(self):
# Верхняя панель с настройками
settings_panel = QHBoxLayout()
settings_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
settings_panel.setSpacing(StyleConstants.SPACING['md'])
# Выбор модели
model_label = QLabel("Модель:")
settings_panel.addWidget(model_label)
self.model_combo = QComboBox()
self.model_combo.currentTextChanged.connect(self.on_model_changed)
settings_panel.addWidget(self.model_combo)
# Выбор сэмплера
sampler_label = QLabel("Сэмплер:")
settings_panel.addWidget(sampler_label)
self.sampler_combo = QComboBox()
self.sampler_combo.currentTextChanged.connect(self.on_sampler_changed)
settings_panel.addWidget(self.sampler_combo)
# Настройки размера
size_label = QLabel("Размер:")
settings_panel.addWidget(size_label)
self.width_spin = QSpinBox()
self.width_spin.setRange(64, 2048)
self.width_spin.setSingleStep(64)
self.width_spin.setValue(512)
settings_panel.addWidget(self.width_spin)
self.height_spin = QSpinBox()
self.height_spin.setRange(64, 2048)
self.height_spin.setSingleStep(64)
self.height_spin.setValue(512)
settings_panel.addWidget(self.height_spin)
settings_panel.addStretch()
self.layout.addLayout(settings_panel)
# Панель промптов
prompts_panel = QVBoxLayout()
prompts_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
prompts_panel.setSpacing(StyleConstants.SPACING['md'])
# Позитивный промпт
prompt_label = QLabel("Промпт:")
prompts_panel.addWidget(prompt_label)
self.prompt_edit = QLineEdit()
self.prompt_edit.setPlaceholderText("Опишите желаемое изображение...")
prompts_panel.addWidget(self.prompt_edit)
# Негативный промпт
negative_prompt_label = QLabel("Негативный промпт:")
prompts_panel.addWidget(negative_prompt_label)
self.negative_prompt_edit = QLineEdit()
self.negative_prompt_edit.setPlaceholderText("Опишите нежелательные элементы...")
prompts_panel.addWidget(self.negative_prompt_edit)
self.layout.addLayout(prompts_panel)
# Панель генерации
generate_panel = QHBoxLayout()
generate_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
generate_panel.setSpacing(StyleConstants.SPACING['md'])
self.steps_spin = QSpinBox()
self.steps_spin.setRange(1, 150)
self.steps_spin.setValue(20)
self.steps_spin.setPrefix("Шаги: ")
generate_panel.addWidget(self.steps_spin)
self.cfg_spin = QSpinBox()
self.cfg_spin.setRange(1, 30)
self.cfg_spin.setValue(7)
self.cfg_spin.setPrefix("CFG: ")
generate_panel.addWidget(self.cfg_spin)
self.batch_size_spin = QSpinBox()
self.batch_size_spin.setRange(1, 4)
self.batch_size_spin.setValue(1)
self.batch_size_spin.setPrefix("Количество: ")
generate_panel.addWidget(self.batch_size_spin)
self.generate_btn = QPushButton("Сгенерировать")
self.generate_btn.setIcon(self.icon_manager.get_icon(IconType.GENERATE))
self.generate_btn.clicked.connect(self.generate_images)
generate_panel.addWidget(self.generate_btn)
generate_panel.addStretch()
self.layout.addLayout(generate_panel)
# Прогресс-бар
progress_layout = QHBoxLayout()
progress_layout.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
self.progress_bar = QProgressBar()
self.progress_bar.setTextVisible(True)
self.progress_bar.setFormat("%p% - %v/%m шагов")
progress_layout.addWidget(self.progress_bar)
self.layout.addLayout(progress_layout)
# Область для результатов
result_layout = QVBoxLayout()
result_layout.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
self.result_label = QLabel()
self.result_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
result_layout.addWidget(self.result_label)
self.layout.addLayout(result_layout)
self.layout.addStretch()
# Обновляем UI
self.update_ui()
def update_ui(self):
"""Обновление UI после загрузки данных"""
# Обновляем список моделей
self.model_combo.clear()
for model in self.model_manager.get_models():
self.model_combo.addItem(model.title, model.name)
# Устанавливаем текущую модель
current_model = self.model_manager.get_current_model()
if current_model:
index = self.model_combo.findData(current_model.name)
if index >= 0:
self.model_combo.setCurrentIndex(index)
# Обновляем список сэмплеров
self.sampler_combo.clear()
for sampler in self.sampler_manager.get_samplers():
self.sampler_combo.addItem(sampler.title, sampler.name)
# Устанавливаем текущий сэмплер
current_sampler = self.sampler_manager.get_current_sampler()
if current_sampler:
index = self.sampler_combo.findData(current_sampler.name)
if index >= 0:
self.sampler_combo.setCurrentIndex(index)
def on_model_changed(self, model_title):
"""Обработка изменения модели"""
model_name = self.model_combo.currentData()
if model_name:
self.model_manager.switch_model(model_name)
def on_sampler_changed(self, sampler_title):
"""Обработка изменения сэмплера"""
sampler_name = self.sampler_combo.currentData()
if sampler_name:
self.sampler_manager.set_current_sampler(sampler_name)
def set_resolution(self, width: int, height: int):
"""Установка разрешения"""
self.width_spin.setValue(width)
self.height_spin.setValue(height)
def generate_images(self):
"""Генерация изображений"""
try:
# Получаем параметры
params = {
"prompt": self.prompt_edit.text(),
"negative_prompt": self.negative_prompt_edit.text(),
"steps": self.steps_spin.value(),
"cfg_scale": self.cfg_spin.value(),
"batch_size": self.batch_size_spin.value(),
"width": self.width_spin.value(),
"height": self.height_spin.value(),
"sampler_name": self.sampler_combo.currentData(),
}
# Отправляем запрос
response = requests.post(
f"{self.model_manager.api_url}/sdapi/v1/txt2img",
json=params
)
if response.status_code == 200:
result = response.json()
# TODO: Отобразить сгенерированные изображения
print("Изображения успешно сгенерированы")
else:
print(f"Ошибка генерации: {response.status_code}")
except Exception as e:
print(f"Ошибка при генерации: {str(e)}")
+145
View File
@@ -0,0 +1,145 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QSpinBox,
QComboBox, QProgressBar, QScrollArea, QFrame)
from PyQt6.QtCore import Qt
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
from ..styles.page import BasePage
class ModelCard(QFrame):
"""Карточка модели"""
def __init__(self, model, parent=None):
super().__init__(parent)
self.model = model
self.setup_ui()
def setup_ui(self):
self.setStyleSheet(f"""
QFrame {{
background-color: {StyleConstants.COLORS['dark']['surface']};
border-radius: {StyleConstants.RADIUS['md']}px;
padding: {StyleConstants.SPACING['md']}px;
margin-bottom: {StyleConstants.SPACING['md']}px;
}}
QLabel {{
color: {StyleConstants.COLORS['dark']['text']};
}}
QPushButton {{
background-color: {StyleConstants.COLORS['primary']};
color: white;
border: none;
border-radius: {StyleConstants.RADIUS['sm']}px;
padding: {StyleConstants.SPACING['sm']}px {StyleConstants.SPACING['md']}px;
}}
QPushButton:hover {{
background-color: {StyleConstants.COLORS['secondary']};
}}
""")
layout = QVBoxLayout(self)
layout.setSpacing(StyleConstants.SPACING['sm'])
# Название модели
title = QLabel(self.model.title)
title.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['lg']};
font-weight: {StyleConstants.FONTS['weight']['bold']};
""")
layout.addWidget(title)
# Имя файла модели
name = QLabel(self.model.name)
name.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['sm']};
color: {StyleConstants.COLORS['dark']['text_secondary']};
""")
layout.addWidget(name)
# Кнопки управления
buttons_layout = QHBoxLayout()
select_btn = QPushButton("Выбрать")
select_btn.setIcon(IconManager.get_instance().get_icon(IconType.SUCCESS))
buttons_layout.addWidget(select_btn)
delete_btn = QPushButton("Удалить")
delete_btn.setIcon(IconManager.get_instance().get_icon(IconType.DELETE))
buttons_layout.addWidget(delete_btn)
buttons_layout.addStretch()
layout.addLayout(buttons_layout)
class ModelsPage(BasePage):
"""Страница управления моделями"""
def __init__(self, model_manager, parent=None):
super().__init__(parent)
self.model_manager = model_manager
self.setup_ui()
def setup_ui(self):
# Верхняя панель
top_panel = QHBoxLayout()
top_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
top_panel.setSpacing(StyleConstants.SPACING['md'])
# Поиск
self.search_edit = QLineEdit()
self.search_edit.setPlaceholderText("Поиск моделей...")
top_panel.addWidget(self.search_edit)
# Кнопка обновления
refresh_btn = QPushButton("Обновить")
refresh_btn.setIcon(IconManager.get_instance().get_icon(IconType.REFRESH))
refresh_btn.clicked.connect(self.update_ui)
top_panel.addWidget(refresh_btn)
# Кнопка добавления
add_btn = QPushButton("Добавить")
add_btn.setIcon(IconManager.get_instance().get_icon(IconType.ADD))
top_panel.addWidget(add_btn)
top_panel.addStretch()
self.layout.addLayout(top_panel)
# Область прокрутки для моделей
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# Контейнер для карточек моделей
self.models_container = QWidget()
self.models_layout = QVBoxLayout(self.models_container)
self.models_layout.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
self.models_layout.setSpacing(0)
scroll_area.setWidget(self.models_container)
self.layout.addWidget(scroll_area)
# Обновляем UI
self.update_ui()
def update_ui(self):
"""Обновление списка моделей"""
# Очищаем контейнер
for i in reversed(range(self.models_layout.count())):
widget = self.models_layout.itemAt(i).widget()
if widget:
widget.deleteLater()
# Добавляем карточки моделей
for model in self.model_manager.get_models():
card = ModelCard(model)
self.models_layout.addWidget(card)
# Добавляем растягивающийся элемент в конец
self.models_layout.addStretch()
+193
View File
@@ -0,0 +1,193 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QComboBox,
QSpinBox, QCheckBox, QFrame)
from PyQt6.QtCore import Qt
from ..styles.page import BasePage
from ..styles.theme import Colors, Spacing, Fonts
from ..styles.icons import IconManager, IconType
from ..styles.theme_manager import ThemeManager
class SettingsSection(QFrame):
def __init__(self, title: str, parent=None):
super().__init__(parent)
self.title = title
self.theme_manager = ThemeManager.get_instance()
self.setup_ui()
def setup_ui(self):
"""Настройка UI секции настроек"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
# Основной layout
layout = QVBoxLayout(self)
layout.setContentsMargins(16, 16, 16, 16)
layout.setSpacing(16)
# Заголовок секции
title_label = QLabel(self.title)
title_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 18px;
font-weight: bold;
}}
""")
layout.addWidget(title_label)
# Контейнер для содержимого
self.content_layout = QVBoxLayout()
self.content_layout.setSpacing(12)
layout.addLayout(self.content_layout)
# Стили
self.setStyleSheet(f"""
QFrame {{
background-color: {colors['surface']};
border: 1px solid {colors['border']};
border-radius: {spacing.MEDIUM}px;
}}
""")
class SettingsPage(BasePage):
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_content()
def setup_content(self):
"""Настройка содержимого страницы"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
# Заголовок
header = QLabel("Настройки")
header.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 24px;
font-weight: bold;
}}
""")
self.layout.addWidget(header)
# API настройки
api_section = SettingsSection("API")
api_url_layout = QVBoxLayout()
api_url_label = QLabel("URL API:")
api_url_label.setStyleSheet(f"color: {colors['text']};")
self.api_url_input = QLineEdit()
self.api_url_input.setPlaceholderText("http://localhost:7860")
api_url_layout.addWidget(api_url_label)
api_url_layout.addWidget(self.api_url_input)
api_section.content_layout.addLayout(api_url_layout)
self.layout.addWidget(api_section)
# UI настройки
ui_section = SettingsSection("Интерфейс")
# Тема
theme_layout = QVBoxLayout()
theme_label = QLabel("Тема:")
theme_label.setStyleSheet(f"color: {colors['text']};")
self.theme_combo = QComboBox()
self.theme_combo.addItems(["Тёмная", "Светлая"])
theme_layout.addWidget(theme_label)
theme_layout.addWidget(self.theme_combo)
ui_section.content_layout.addLayout(theme_layout)
# Размер шрифта
font_size_layout = QVBoxLayout()
font_size_label = QLabel("Размер шрифта:")
font_size_label.setStyleSheet(f"color: {colors['text']};")
self.font_size_spin = QSpinBox()
self.font_size_spin.setRange(10, 24)
self.font_size_spin.setValue(14)
font_size_layout.addWidget(font_size_label)
font_size_layout.addWidget(self.font_size_spin)
ui_section.content_layout.addLayout(font_size_layout)
self.layout.addWidget(ui_section)
# Настройки генерации
generation_section = SettingsSection("Генерация")
# Качество по умолчанию
quality_layout = QVBoxLayout()
quality_label = QLabel("Качество по умолчанию:")
quality_label.setStyleSheet(f"color: {colors['text']};")
self.quality_combo = QComboBox()
self.quality_combo.addItems(["Низкое", "Среднее", "Высокое"])
quality_layout.addWidget(quality_label)
quality_layout.addWidget(self.quality_combo)
generation_section.content_layout.addLayout(quality_layout)
# Размер по умолчанию
size_layout = QVBoxLayout()
size_label = QLabel("Размер по умолчанию:")
size_label.setStyleSheet(f"color: {colors['text']};")
self.size_combo = QComboBox()
self.size_combo.addItems(["512x512", "768x768", "1024x1024"])
size_layout.addWidget(size_label)
size_layout.addWidget(self.size_combo)
generation_section.content_layout.addLayout(size_layout)
self.layout.addWidget(generation_section)
# Кнопки
buttons_layout = QHBoxLayout()
self.save_btn = QPushButton("Сохранить")
self.save_btn.setMinimumWidth(150)
self.save_btn.setStyleSheet(f"""
QPushButton {{
background-color: {colors['primary']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
buttons_layout.addWidget(self.save_btn)
self.reset_btn = QPushButton("Сбросить")
self.reset_btn.setMinimumWidth(150)
self.reset_btn.setStyleSheet(f"""
QPushButton {{
background-color: transparent;
color: {colors['primary']};
border: 1px solid {colors['primary']};
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
color: white;
border: none;
}}
QPushButton:pressed {{
background-color: {colors['active']};
color: white;
border: none;
}}
""")
buttons_layout.addWidget(self.reset_btn)
buttons_layout.addStretch()
self.layout.addLayout(buttons_layout)
# Растягиваем пространство
self.layout.addStretch()
+316
View File
@@ -0,0 +1,316 @@
PROMPT_TRANSLATIONS = {
# Персонажи
"Девушка": "girl",
"Парень": "boy",
"Мужчина": "man",
"Женщина": "woman",
"Ребенок": "child",
"Малыш": "baby",
"Пожилой человек": "elderly person",
"Старик": "old man",
"Старушка": "old woman",
# Профессии
"Художник": "artist",
"Музыкант": "musician",
"Писатель": "writer",
"Учитель": "teacher",
"Врач": "doctor",
"Инженер": "engineer",
"Программист": "programmer",
"Повар": "chef",
"Полицейский": "police officer",
"Пожарный": "firefighter",
# Животные
"Кошка": "cat",
"Собака": "dog",
"Птица": "bird",
"Рыба": "fish",
"Лошадь": "horse",
"Корова": "cow",
"Овца": "sheep",
"Коза": "goat",
"Кролик": "rabbit",
"Хомяк": "hamster",
# Природа
"Гора": "mountain",
"Море": "sea",
"Океан": "ocean",
"Река": "river",
"Лес": "forest",
"Поле": "field",
"Цветок": "flower",
"Дерево": "tree",
"Трава": "grass",
"Песок": "sand",
# Погода
"Солнце": "sun",
"Дождь": "rain",
"Снег": "snow",
"Ветер": "wind",
"Туман": "fog",
"Облако": "cloud",
"Гроза": "thunderstorm",
"Радуга": "rainbow",
"Мороз": "frost",
"Иней": "hoarfrost",
# Время суток
"Утро": "morning",
"День": "day",
"Вечер": "evening",
"Ночь": "night",
"Рассвет": "dawn",
"Закат": "sunset",
"Полдень": "noon",
"Полночь": "midnight",
# Сезоны
"Весна": "spring",
"Лето": "summer",
"Осень": "autumn",
"Зима": "winter",
# Эмоции
"Счастье": "happiness",
"Грусть": "sadness",
"Гнев": "anger",
"Страх": "fear",
"Удивление": "surprise",
"Отвращение": "disgust",
"Любовь": "love",
"Ненависть": "hate",
"Спокойствие": "calmness",
"Волнение": "excitement",
# Действия
"Бег": "running",
"Ходьба": "walking",
"Прыжок": "jumping",
"Плавание": "swimming",
"Танцы": "dancing",
"Пение": "singing",
"Игра": "playing",
"Работа": "working",
"Отдых": "resting",
"Сон": "sleeping",
# Одежда
"Платье": "dress",
"Рубашка": "shirt",
"Брюки": "pants",
"Юбка": "skirt",
"Куртка": "jacket",
"Пальто": "coat",
"Шапка": "hat",
"Обувь": "shoes",
"Перчатки": "gloves",
"Шарф": "scarf",
# Цвета
"Красный": "red",
"Синий": "blue",
"Зеленый": "green",
"Желтый": "yellow",
"Белый": "white",
"Черный": "black",
"Серый": "gray",
"Коричневый": "brown",
"Оранжевый": "orange",
"Фиолетовый": "purple",
# Материалы
"Дерево": "wood",
"Металл": "metal",
"Стекло": "glass",
"Пластик": "plastic",
"Ткань": "fabric",
"Бумага": "paper",
"Камень": "stone",
"Керамика": "ceramics",
"Кожа": "leather",
"Резина": "rubber",
# Технологии
"Компьютер": "computer",
"Телефон": "phone",
"Планшет": "tablet",
"Робот": "robot",
"Дрон": "drone",
"Смартфон": "smartphone",
"Ноутбук": "laptop",
"Принтер": "printer",
"Камера": "camera",
"Наушники": "headphones",
# Транспорт
"Машина": "car",
"Велосипед": "bicycle",
"Мотоцикл": "motorcycle",
"Поезд": "train",
"Самолет": "airplane",
"Корабль": "ship",
"Автобус": "bus",
"Трамвай": "tram",
"Метро": "subway",
"Вертолет": "helicopter",
# Еда
"Фрукты": "fruits",
"Овощи": "vegetables",
"Мясо": "meat",
"Рыба": "fish",
"Хлеб": "bread",
"Молоко": "milk",
"Сок": "juice",
"Кофе": "coffee",
"Чай": "tea",
"Сладости": "sweets",
# Дом
"Дом": "house",
"Квартира": "apartment",
"Комната": "room",
"Кухня": "kitchen",
"Спальня": "bedroom",
"Ванная": "bathroom",
"Гостиная": "living room",
"Балкон": "balcony",
"Подвал": "basement",
"Чердак": "attic",
# Музыка
"Гитара": "guitar",
"Пианино": "piano",
"Скрипка": "violin",
"Барабаны": "drums",
"Флейта": "flute",
"Саксофон": "saxophone",
"Труба": "trumpet",
"Бас": "bass",
"Синтезатор": "synthesizer",
"Микрофон": "microphone",
# Спорт
"Футбол": "football",
"Баскетбол": "basketball",
"Волейбол": "volleyball",
"Теннис": "tennis",
"Хоккей": "hockey",
"Бег": "running",
"Плавание": "swimming",
"Бокс": "boxing",
"Йога": "yoga",
"Гимнастика": "gymnastics",
# Искусство
"Картина": "painting",
"Рисунок": "drawing",
"Скульптура": "sculpture",
"Фотография": "photography",
"Кино": "movie",
"Театр": "theater",
"Музыка": "music",
"Танец": "dance",
"Поэзия": "poetry",
"Литература": "literature",
# Наука
"Физика": "physics",
"Химия": "chemistry",
"Биология": "biology",
"Математика": "mathematics",
"Астрономия": "astronomy",
"Геология": "geology",
"Экология": "ecology",
"Психология": "psychology",
"История": "history",
"География": "geography",
# Время
"Секунда": "second",
"Минута": "minute",
"Час": "hour",
"День": "day",
"Неделя": "week",
"Месяц": "month",
"Год": "year",
"Век": "century",
"Эпоха": "era",
"Период": "period",
# География
"Страна": "country",
"Город": "city",
"Деревня": "village",
"Река": "river",
"Озеро": "lake",
"Море": "sea",
"Океан": "ocean",
"Гора": "mountain",
"Пустыня": "desert",
"Джунгли": "jungle",
# Космос
"Солнце": "sun",
"Луна": "moon",
"Звезда": "star",
"Планета": "planet",
"Галактика": "galaxy",
"Вселенная": "universe",
"Астероид": "asteroid",
"Комета": "comet",
"Спутник": "satellite",
"Космический корабль": "spaceship",
# Фэнтези
"Дракон": "dragon",
"Единорог": "unicorn",
"Фея": "fairy",
"Волшебник": "wizard",
"Ведьма": "witch",
"Гоблин": "goblin",
"Эльф": "elf",
"Гном": "dwarf",
"Орк": "orc",
"Тролль": "troll",
# Мифология
"Бог": "god",
"Богиня": "goddess",
"Герой": "hero",
"Миф": "myth",
"Легенда": "legend",
"Демон": "demon",
"Ангел": "angel",
"Призрак": "ghost",
"Вампир": "vampire",
"Оборотень": "werewolf",
# Стили искусства
"Реализм": "realism",
"Импрессионизм": "impressionism",
"Экспрессионизм": "expressionism",
"Сюрреализм": "surrealism",
"Абстракционизм": "abstract art",
"Поп-арт": "pop art",
"Модернизм": "modernism",
"Постмодернизм": "postmodernism",
"Кубизм": "cubism",
"Футуризм": "futurism",
# Эпохи
"Древний мир": "ancient world",
"Средневековье": "middle ages",
"Ренессанс": "renaissance",
"Барокко": "baroque",
"Классицизм": "classicism",
"Романтизм": "romanticism",
"Викторианская эпоха": "victorian era",
"Модерн": "art nouveau",
"Ар-деко": "art deco",
"Современность": "modern era"
}
+70 -45
View File
@@ -3,6 +3,7 @@ from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget,
QScrollArea, QWidget, QCheckBox, QFrame) QScrollArea, QWidget, QCheckBox, QFrame)
from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtCore import Qt, pyqtSignal
from .prompt_categories import PROMPT_CATEGORIES from .prompt_categories import PROMPT_CATEGORIES
from .prompt_translations import PROMPT_TRANSLATIONS
class PromptWindow(QDialog): class PromptWindow(QDialog):
prompt_selected = pyqtSignal(str) prompt_selected = pyqtSignal(str)
@@ -18,87 +19,105 @@ class PromptWindow(QDialog):
def setup_ui(self): def setup_ui(self):
self.setStyleSheet(""" self.setStyleSheet("""
QDialog { QDialog {
background-color: #2b2b2b; background-color: #1e1e1e;
min-width: 1500px; min-width: 1200px;
min-height: 700px; min-height: 800px;
} }
QScrollArea { QScrollArea {
background-color: #1e1e1e; background-color: #252526;
border: 1px solid #3b3b3b; border: none;
border-radius: 4px; border-radius: 8px;
padding: 8px;
} }
QScrollArea > QWidget > QWidget { QScrollArea > QWidget > QWidget {
background-color: #1e1e1e; background-color: #252526;
} }
QLabel { QLabel {
color: #ffffff; color: #d4d4d4;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: 600;
padding: 8px; padding: 12px;
background-color: #3b3b3b; background-color: #2d2d2d;
border-radius: 4px; border-radius: 6px;
margin-bottom: 8px;
} }
QCheckBox { QCheckBox {
color: #ffffff; color: #d4d4d4;
font-size: 14px; font-size: 13px;
padding: 4px; padding: 6px;
spacing: 8px; spacing: 8px;
} }
QCheckBox:hover {
background-color: #2d2d2d;
border-radius: 4px;
}
QCheckBox::indicator { QCheckBox::indicator {
width: 18px; width: 18px;
height: 18px; height: 18px;
border-radius: 4px;
} }
QCheckBox::indicator:unchecked { QCheckBox::indicator:unchecked {
border: 2px solid #555555; border: 2px solid #565656;
background-color: #3b3b3b; background-color: #252526;
border-radius: 3px;
} }
QCheckBox::indicator:checked { QCheckBox::indicator:checked {
border: 2px solid #0d6efd; border: 2px solid #007acc;
background-color: #0d6efd; background-color: #007acc;
border-radius: 3px;
} }
QCheckBox::indicator:hover { QCheckBox::indicator:hover {
border-color: #0b5ed7; border-color: #007acc;
} }
QPushButton { QPushButton {
background-color: #0d6efd; background-color: #2d2d2d;
color: white; color: #d4d4d4;
border: none; border: 1px solid #3e3e3e;
border-radius: 4px; border-radius: 6px;
padding: 8px 16px; padding: 8px 16px;
font-weight: bold; font-weight: 500;
min-width: 120px; min-width: 120px;
font-size: 13px;
} }
QPushButton:hover { QPushButton:hover {
background-color: #0b5ed7; background-color: #3e3e3e;
border-color: #565656;
} }
QPushButton:pressed { QPushButton:pressed {
background-color: #0a58ca; background-color: #565656;
} }
QLineEdit { QLineEdit {
background-color: #3b3b3b; background-color: #252526;
color: white; color: #d4d4d4;
border: 1px solid #555555; border: 1px solid #3e3e3e;
border-radius: 4px; border-radius: 6px;
padding: 8px; padding: 8px 12px;
font-size: 14px; font-size: 13px;
min-height: 24px; min-height: 32px;
}
QLineEdit:focus {
border-color: #007acc;
} }
QFrame { QFrame {
background-color: #1e1e1e; background-color: #252526;
border: 1px solid #3b3b3b; border: 1px solid #3e3e3e;
border-radius: 4px; border-radius: 8px;
padding: 12px;
margin: 4px;
}
QFrame:hover {
border-color: #565656;
} }
""") """)
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.setContentsMargins(16, 16, 16, 16)
layout.setSpacing(12)
# Поиск # Поиск
search_layout = QHBoxLayout() search_layout = QHBoxLayout()
search_label = QLabel("Поиск:") search_layout.setSpacing(8)
search_label = QLabel("🔍 Поиск:")
search_label.setStyleSheet("background: transparent; padding: 0;")
self.search_input = QLineEdit() self.search_input = QLineEdit()
self.search_input.setPlaceholderText("Введите текст для поиска...")
self.search_input.textChanged.connect(self.filter_prompts) self.search_input.textChanged.connect(self.filter_prompts)
search_layout.addWidget(search_label) search_layout.addWidget(search_label)
search_layout.addWidget(self.search_input) search_layout.addWidget(self.search_input)
@@ -109,22 +128,26 @@ class PromptWindow(QDialog):
categories_scroll.setWidgetResizable(True) categories_scroll.setWidgetResizable(True)
categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn) categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
categories_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) categories_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
categories_scroll.setMinimumHeight(600)
categories_widget = QWidget() categories_widget = QWidget()
self.categories_layout = QHBoxLayout(categories_widget) self.categories_layout = QHBoxLayout(categories_widget)
self.categories_layout.setSpacing(10) self.categories_layout.setSpacing(12)
self.categories_layout.setContentsMargins(12, 12, 12, 12)
categories_scroll.setWidget(categories_widget) categories_scroll.setWidget(categories_widget)
layout.addWidget(categories_scroll) layout.addWidget(categories_scroll)
# Кнопки # Кнопки
buttons_layout = QHBoxLayout() buttons_layout = QHBoxLayout()
add_button = QPushButton("Добавить выбранные") buttons_layout.setSpacing(8)
add_button = QPushButton("✨ Добавить выбранные")
add_button.clicked.connect(self.add_selected) add_button.clicked.connect(self.add_selected)
close_button = QPushButton("Закрыть") close_button = QPushButton("❌ Закрыть")
close_button.clicked.connect(self.close) close_button.clicked.connect(self.close)
buttons_layout.addWidget(add_button) buttons_layout.addWidget(add_button)
buttons_layout.addWidget(close_button) buttons_layout.addWidget(close_button)
buttons_layout.addStretch()
layout.addLayout(buttons_layout) layout.addLayout(buttons_layout)
def load_categories(self): def load_categories(self):
@@ -195,5 +218,7 @@ class PromptWindow(QDialog):
def add_selected(self): def add_selected(self):
"""Добавление выбранных промптов""" """Добавление выбранных промптов"""
if self.selected_prompts: if self.selected_prompts:
prompts_text = ", ".join(sorted(self.selected_prompts)) # Преобразуем русские названия в английские
translated_prompts = [PROMPT_TRANSLATIONS.get(prompt, prompt) for prompt in self.selected_prompts]
prompts_text = ", ".join(sorted(translated_prompts))
self.prompt_selected.emit(prompts_text) self.prompt_selected.emit(prompts_text)
+89 -19
View File
@@ -2,6 +2,17 @@ from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QComboBox, QLabel) QComboBox, QLabel)
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal
import requests import requests
from typing import List, Dict
import os
from dotenv import load_dotenv
# Загружаем переменные окружения
load_dotenv()
class Sampler:
def __init__(self, name: str, title: str = None):
self.name = name
self.title = title or name
class SamplerManager(QWidget): class SamplerManager(QWidget):
sampler_changed = pyqtSignal(str) sampler_changed = pyqtSignal(str)
@@ -13,8 +24,50 @@ class SamplerManager(QWidget):
self.load_samplers() self.load_samplers()
def setup_ui(self): def setup_ui(self):
self.setStyleSheet("""
QWidget {
background-color: transparent;
}
QLabel {
color: #d4d4d4;
font-size: 13px;
font-weight: 500;
margin-right: 8px;
}
QComboBox {
background-color: #252526;
color: #d4d4d4;
border: 1px solid #3e3e3e;
border-radius: 6px;
padding: 6px 12px;
min-width: 180px;
font-size: 13px;
}
QComboBox:hover {
border-color: #565656;
}
QComboBox:focus {
border-color: #007acc;
}
QComboBox::drop-down {
border: none;
width: 20px;
}
QComboBox::down-arrow {
image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTggMTFMNCBTTDEyIDUiIHN0cm9rZT0iI2Q0ZDRkNCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+);
}
QComboBox QAbstractItemView {
background-color: #252526;
color: #d4d4d4;
border: 1px solid #3e3e3e;
selection-background-color: #094771;
outline: none;
}
""")
layout = QHBoxLayout(self) layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(8)
# Метка # Метка
label = QLabel("Сэмплер:") label = QLabel("Сэмплер:")
@@ -22,34 +75,32 @@ class SamplerManager(QWidget):
# Выпадающий список сэмплеров # Выпадающий список сэмплеров
self.sampler_combo = QComboBox() self.sampler_combo = QComboBox()
self.sampler_combo.setFixedHeight(32)
self.sampler_combo.currentTextChanged.connect(self.on_sampler_changed) self.sampler_combo.currentTextChanged.connect(self.on_sampler_changed)
layout.addWidget(self.sampler_combo) layout.addWidget(self.sampler_combo)
layout.addStretch() layout.addStretch()
def load_samplers(self): def load_samplers(self):
"""Загрузить список доступных сэмплеров""" """Загрузка списка сэмплеров с сервера"""
try: try:
response = requests.get(f"{self.api_url}/sdapi/v1/samplers") response = requests.get(f"{self.api_url}/sdapi/v1/samplers")
if response.status_code == 200: if response.status_code == 200:
samplers = response.json() samplers_data = response.json()
current_sampler = self.sampler_combo.currentText() self.samplers = [
Sampler(sampler['name'], sampler.get('title'))
for sampler in samplers_data
]
self.sampler_combo.clear() # По умолчанию выбираем Euler a
for sampler in samplers: self.current_sampler = next(
self.sampler_combo.addItem(sampler.get('name', '')) (sampler for sampler in self.samplers if sampler.name == "Euler a"),
self.samplers[0] if self.samplers else None
# Восстанавливаем выбранный сэмплер, если он всё ещё доступен )
index = self.sampler_combo.findText(current_sampler)
if index >= 0:
self.sampler_combo.setCurrentIndex(index)
elif self.sampler_combo.count() > 0:
# По умолчанию выбираем Euler a
default_index = self.sampler_combo.findText("Euler a")
if default_index >= 0:
self.sampler_combo.setCurrentIndex(default_index)
except Exception as e: except Exception as e:
print(f"Ошибка при загрузке сэмплеров: {str(e)}") print(f"Ошибка загрузки сэмплеров: {str(e)}")
self.samplers = []
self.current_sampler = None
def on_sampler_changed(self, sampler_name): def on_sampler_changed(self, sampler_name):
"""Обработка смены сэмплера""" """Обработка смены сэмплера"""
@@ -60,6 +111,25 @@ class SamplerManager(QWidget):
self.api_url = new_url self.api_url = new_url
self.load_samplers() self.load_samplers()
def get_samplers(self):
"""Возвращает список доступных сэмплеров"""
return self.samplers
def get_sampler_names(self):
"""Возвращает список имен сэмплеров"""
return [sampler.name for sampler in self.samplers]
def get_current_sampler(self): def get_current_sampler(self):
"""Получить текущий выбранный сэмплер""" """Возвращает текущий сэмплер"""
return self.sampler_combo.currentText() return self.current_sampler
def set_current_sampler(self, sampler_name: str) -> bool:
"""Установка текущего сэмплера"""
sampler = next(
(s for s in self.samplers if s.name == sampler_name),
None
)
if sampler:
self.current_sampler = sampler
return True
return False
+261
View File
@@ -0,0 +1,261 @@
from PyQt6.QtWidgets import (QMenu,
QDialog, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QCheckBox,
QPushButton, QComboBox, QSpinBox)
from PyQt6.QtGui import QIcon, QAction, QActionGroup
from PyQt6.QtCore import Qt
class SettingsMenu(QMenu):
def __init__(self, parent=None):
super().__init__("⚙️ Настройки", parent)
self.setStyleSheet("""
QMenu {
background-color: #2b2b2b;
border: 1px solid #3b3b3b;
border-radius: 8px;
padding: 5px;
}
QMenu::item {
background-color: transparent;
padding: 8px 25px;
margin: 2px;
border-radius: 4px;
color: #ffffff;
font-size: 13px;
}
QMenu::item:selected {
background-color: #3b3b3b;
}
QMenu::separator {
height: 1px;
background-color: #3b3b3b;
margin: 5px 15px;
}
""")
self.setup_menu()
def setup_menu(self):
# API настройки
api_action = QAction("🌐 API настройки", self)
api_action.triggered.connect(self.show_api_settings)
# Настройки интерфейса
ui_action = QAction("🎨 Настройки интерфейса", self)
ui_action.triggered.connect(self.show_ui_settings)
# Настройки генерации
generation_action = QAction("⚡ Настройки генерации", self)
generation_action.triggered.connect(self.show_generation_settings)
# Горячие клавиши
hotkeys_action = QAction("⌨️ Горячие клавиши", self)
hotkeys_action.triggered.connect(self.show_hotkeys_settings)
# Добавляем действия в меню
self.addAction(api_action)
self.addAction(ui_action)
self.addAction(generation_action)
self.addSeparator()
self.addAction(hotkeys_action)
def show_api_settings(self):
dialog = APISettingsDialog(self.parent())
dialog.exec()
def show_ui_settings(self):
dialog = UISettingsDialog(self.parent())
dialog.exec()
def show_generation_settings(self):
dialog = GenerationSettingsDialog(self.parent())
dialog.exec()
def show_hotkeys_settings(self):
dialog = HotkeysSettingsDialog(self.parent())
dialog.exec()
class BaseSettingsDialog(QDialog):
def __init__(self, title, parent=None):
super().__init__(parent)
self.setWindowTitle(title)
self.setup_base_ui()
def setup_base_ui(self):
self.setStyleSheet("""
QDialog {
background-color: #2b2b2b;
min-width: 400px;
}
QLabel {
color: #ffffff;
font-size: 13px;
}
QLineEdit, QComboBox, QSpinBox {
background-color: #3b3b3b;
border: 1px solid #555555;
border-radius: 4px;
padding: 5px;
color: #ffffff;
min-width: 200px;
}
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-weight: bold;
min-width: 100px;
}
QPushButton:hover {
background-color: #0b5ed7;
}
QCheckBox {
color: #ffffff;
}
""")
self.layout = QVBoxLayout(self)
self.layout.setSpacing(15)
self.layout.setContentsMargins(20, 20, 20, 20)
class APISettingsDialog(BaseSettingsDialog):
def __init__(self, parent=None):
super().__init__("🌐 API настройки", parent)
self.setup_ui()
def setup_ui(self):
# API URL
url_layout = QHBoxLayout()
url_label = QLabel("API URL:")
self.url_input = QLineEdit(self.parent().api_url_input.text())
url_layout.addWidget(url_label)
url_layout.addWidget(self.url_input)
self.layout.addLayout(url_layout)
# Кнопки
buttons_layout = QHBoxLayout()
save_button = QPushButton("Сохранить")
save_button.clicked.connect(self.save_settings)
cancel_button = QPushButton("Отмена")
cancel_button.clicked.connect(self.reject)
buttons_layout.addWidget(save_button)
buttons_layout.addWidget(cancel_button)
self.layout.addLayout(buttons_layout)
def save_settings(self):
self.parent().api_url_input.setText(self.url_input.text())
self.accept()
class UISettingsDialog(BaseSettingsDialog):
def __init__(self, parent=None):
super().__init__("🎨 Настройки интерфейса", parent)
self.setup_ui()
def setup_ui(self):
# Тема
theme_layout = QHBoxLayout()
theme_label = QLabel("Тема:")
self.theme_combo = QComboBox()
self.theme_combo.addItems(["Тёмная", "Светлая"])
theme_layout.addWidget(theme_label)
theme_layout.addWidget(self.theme_combo)
self.layout.addLayout(theme_layout)
# Размер шрифта
font_layout = QHBoxLayout()
font_label = QLabel("Размер шрифта:")
self.font_spin = QSpinBox()
self.font_spin.setRange(8, 24)
self.font_spin.setValue(14)
font_layout.addWidget(font_label)
font_layout.addWidget(self.font_spin)
self.layout.addLayout(font_layout)
# Кнопки
buttons_layout = QHBoxLayout()
save_button = QPushButton("Сохранить")
save_button.clicked.connect(self.save_settings)
cancel_button = QPushButton("Отмена")
cancel_button.clicked.connect(self.reject)
buttons_layout.addWidget(save_button)
buttons_layout.addWidget(cancel_button)
self.layout.addLayout(buttons_layout)
def save_settings(self):
# TODO: Применить настройки интерфейса
self.accept()
class GenerationSettingsDialog(BaseSettingsDialog):
def __init__(self, parent=None):
super().__init__("⚡ Настройки генерации", parent)
self.setup_ui()
def setup_ui(self):
# Качество по умолчанию
quality_layout = QHBoxLayout()
quality_label = QLabel("Качество по умолчанию:")
self.quality_combo = QComboBox()
self.quality_combo.addItems(["Низкое", "Среднее", "Высокое"])
quality_layout.addWidget(quality_label)
quality_layout.addWidget(self.quality_combo)
self.layout.addLayout(quality_layout)
# Размер по умолчанию
size_layout = QHBoxLayout()
size_label = QLabel("Размер по умолчанию:")
self.size_combo = QComboBox()
self.size_combo.addItems(["512x512", "768x512", "512x768"])
size_layout.addWidget(size_label)
size_layout.addWidget(self.size_combo)
self.layout.addLayout(size_layout)
# Кнопки
buttons_layout = QHBoxLayout()
save_button = QPushButton("Сохранить")
save_button.clicked.connect(self.save_settings)
cancel_button = QPushButton("Отмена")
cancel_button.clicked.connect(self.reject)
buttons_layout.addWidget(save_button)
buttons_layout.addWidget(cancel_button)
self.layout.addLayout(buttons_layout)
def save_settings(self):
# TODO: Применить настройки генерации
self.accept()
class HotkeysSettingsDialog(BaseSettingsDialog):
def __init__(self, parent=None):
super().__init__("⌨️ Горячие клавиши", parent)
self.setup_ui()
def setup_ui(self):
# Генерация
generate_layout = QHBoxLayout()
generate_label = QLabel("Генерация:")
self.generate_input = QLineEdit("Ctrl+G")
generate_layout.addWidget(generate_label)
generate_layout.addWidget(self.generate_input)
self.layout.addLayout(generate_layout)
# Открыть консоль
console_layout = QHBoxLayout()
console_label = QLabel("Открыть консоль:")
self.console_input = QLineEdit("Ctrl+`")
console_layout.addWidget(console_label)
console_layout.addWidget(self.console_input)
self.layout.addLayout(console_layout)
# Кнопки
buttons_layout = QHBoxLayout()
save_button = QPushButton("Сохранить")
save_button.clicked.connect(self.save_settings)
cancel_button = QPushButton("Отмена")
cancel_button.clicked.connect(self.reject)
buttons_layout.addWidget(save_button)
buttons_layout.addWidget(cancel_button)
self.layout.addLayout(buttons_layout)
def save_settings(self):
# TODO: Применить настройки горячих клавиш
self.accept()
+123
View File
@@ -0,0 +1,123 @@
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFrame
from PyQt6.QtCore import Qt, pyqtSignal
from .size_presets import SIZE_PRESETS
from dataclasses import dataclass
from typing import List, Dict
@dataclass
class SizePreset:
name: str
width: int
height: int
class SizePresetManager(QWidget):
size_changed = pyqtSignal(int, int) # Сигнал для изменения размера
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
self.presets = [
SizePreset("512x512", 512, 512),
SizePreset("768x768", 768, 768),
SizePreset("1024x1024", 1024, 1024),
SizePreset("512x768", 512, 768),
SizePreset("768x512", 768, 512),
SizePreset("512x1024", 512, 1024),
SizePreset("1024x512", 1024, 512),
SizePreset("768x1024", 768, 1024),
SizePreset("1024x768", 1024, 768),
]
def setup_ui(self):
layout = QVBoxLayout(self)
layout.setSpacing(2)
# Заголовок
title = QLabel("Размеры:")
title.setStyleSheet("""
QLabel {
color: #ffffff;
font-size: 12px;
font-weight: bold;
padding: 4px;
background-color: #3b3b3b;
border-radius: 4px;
}
""")
layout.addWidget(title)
# Создаем фрейм для кнопок
buttons_frame = QFrame()
buttons_frame.setStyleSheet("""
QFrame {
background-color: #2b2b2b;
border: 1px solid #3b3b3b;
border-radius: 4px;
padding: 2px;
}
""")
buttons_layout = QVBoxLayout(buttons_frame)
buttons_layout.setSpacing(2)
# Создаем две строки кнопок
row1_layout = QHBoxLayout()
row2_layout = QHBoxLayout()
# Разделяем пресеты на две группы
presets = list(SIZE_PRESETS.items())
half = len(presets) // 2
# Добавляем кнопки в первую строку
for name, (width, height) in presets[:half]:
button = self.create_preset_button(name, width, height)
row1_layout.addWidget(button)
# Добавляем кнопки во вторую строку
for name, (width, height) in presets[half:]:
button = self.create_preset_button(name, width, height)
row2_layout.addWidget(button)
buttons_layout.addLayout(row1_layout)
buttons_layout.addLayout(row2_layout)
layout.addWidget(buttons_frame)
def create_preset_button(self, name, width, height):
"""Создание кнопки пресета с улучшенным дизайном"""
button = QPushButton(name)
button.setStyleSheet(f"""
QPushButton {{
background-color: #3b3b3b;
color: white;
border: 1px solid #555555;
border-radius: 4px;
padding: 4px;
font-size: 11px;
min-width: 80px;
text-align: center;
}}
QPushButton:hover {{
background-color: #4a4a4a;
border-color: #666666;
}}
QPushButton:pressed {{
background-color: #0d6efd;
border-color: #0b5ed7;
}}
""")
button.clicked.connect(lambda checked, w=width, h=height: self.on_preset_clicked(w, h))
return button
def on_preset_clicked(self, width, height):
"""Обработчик нажатия на кнопку пресета"""
self.size_changed.emit(width, height)
def get_preset_names(self) -> List[str]:
"""Возвращает список имен пресетов"""
return [preset.name for preset in self.presets]
def get_preset(self, name: str) -> SizePreset:
"""Возвращает пресет по имени"""
return next(
(preset for preset in self.presets if preset.name == name),
None
)
+8
View File
@@ -0,0 +1,8 @@
SIZE_PRESETS = {
"512x768": (512, 768),
"768x512": (768, 512),
"512x512": (512, 512),
"768x432": (768, 432),
"432x768": (432, 768),
"600x800": (600, 800)
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+75
View File
@@ -0,0 +1,75 @@
from PyQt6.QtWidgets import QMainWindow, QWidget, QVBoxLayout
from PyQt6.QtCore import QEasingCurve, QPropertyAnimation, QRect
from .theme_manager import ThemeManager
class BaseWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_window()
def setup_window(self):
"""Базовая настройка окна"""
# Создаем центральный виджет
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
# Основной layout
self.main_layout = QVBoxLayout(self.central_widget)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setSpacing(0)
# Применяем тему
self.theme_manager.apply_theme()
def animate_window(self, start_geometry: QRect, end_geometry: QRect, duration: int = 300):
"""Анимация окна"""
self.animation = QPropertyAnimation(self, b"geometry")
self.animation.setDuration(duration)
self.animation.setStartValue(start_geometry)
self.animation.setEndValue(end_geometry)
self.animation.setEasingCurve(QEasingCurve.Type.OutCubic)
self.animation.start()
def show_with_animation(self):
"""Показать окно с анимацией"""
# Сохраняем конечную геометрию
end_geometry = self.geometry()
# Устанавливаем начальную геометрию (уменьшенную и прозрачную)
start_geometry = QRect(
end_geometry.x() + end_geometry.width() // 2,
end_geometry.y() + end_geometry.height() // 2,
0,
0
)
# Запускаем анимацию
self.animate_window(start_geometry, end_geometry)
super().show()
def hide_with_animation(self):
"""Скрыть окно с анимацией"""
# Сохраняем начальную геометрию
start_geometry = self.geometry()
# Устанавливаем конечную геометрию (уменьшенную и прозрачную)
end_geometry = QRect(
start_geometry.x() + start_geometry.width() // 2,
start_geometry.y() + start_geometry.height() // 2,
0,
0
)
# Запускаем анимацию
self.animation = QPropertyAnimation(self, b"geometry")
self.animation.setDuration(300)
self.animation.setStartValue(start_geometry)
self.animation.setEndValue(end_geometry)
self.animation.setEasingCurve(QEasingCurve.Type.InCubic)
self.animation.finished.connect(super().hide)
self.animation.start()
def toggle_theme(self):
"""Переключение темы"""
self.theme_manager.toggle_theme()
+102
View File
@@ -0,0 +1,102 @@
from enum import Enum, auto
from PyQt6.QtGui import QIcon
from pathlib import Path
import requests
import os
class IconType(Enum):
"""Типы иконок"""
HOME = auto()
MODELS = auto()
SETTINGS = auto()
GENERATE = auto()
ADD = auto()
DELETE = auto()
REFRESH = auto()
SAVE = auto()
CLOSE = auto()
SUCCESS = auto()
# Навигация
MENU = "menu"
BACK = "arrow-back"
FORWARD = "arrow-forward"
# Действия
REMOVE = "remove"
EDIT = "edit"
SEARCH = "search"
# Медиа
IMAGE = auto()
VIDEO = "video"
AUDIO = "audio"
PLAY = "play"
PAUSE = "pause"
STOP = "stop"
# Статусы
WARNING = "warning"
ERROR = "error"
INFO = "info"
# Интерфейс
MINIMIZE = "minimize"
MAXIMIZE = "maximize"
RESTORE = "restore"
# Тема
LIGHT_MODE = "light-mode"
DARK_MODE = "dark-mode"
class IconManager:
"""Менеджер иконок"""
_instance = None
def __init__(self):
self.icons = {}
self.load_icons()
@classmethod
def get_instance(cls):
"""Получить экземпляр менеджера иконок (Singleton)"""
if cls._instance is None:
cls._instance = IconManager()
return cls._instance
def load_icons(self):
"""Загрузка иконок"""
icons_dir = Path("resources/icons")
# Сопоставление типов иконок с файлами
icon_files = {
IconType.HOME: "home.svg",
IconType.MODELS: "models.svg",
IconType.SETTINGS: "settings.svg",
IconType.GENERATE: "generate.svg",
IconType.ADD: "add.svg",
IconType.DELETE: "delete.svg",
IconType.REFRESH: "refresh.svg",
IconType.SAVE: "save.svg",
IconType.CLOSE: "close.svg",
IconType.SUCCESS: "success.svg",
}
# Загружаем иконки
for icon_type, filename in icon_files.items():
icon_path = icons_dir / filename
if icon_path.exists():
self.icons[icon_type] = QIcon(str(icon_path))
else:
print(f"Иконка не найдена: {icon_path}")
def get_icon(self, icon_type: IconType) -> QIcon:
"""Получить иконку по типу"""
return self.icons.get(icon_type, QIcon())
def get_themed_icon(self, icon_type: IconType, theme: str) -> QIcon:
"""Получение иконки с учетом темы"""
icon_file = Path("resources/icons") / theme / f"{icon_type.value}.svg"
if icon_file.exists():
return QIcon(str(icon_file))
return self.get_icon(icon_type)
+170
View File
@@ -0,0 +1,170 @@
/* Основные стили */
QMainWindow {
background: #1C1C1E;
}
/* Навигационная панель */
NavigationPanel {
background-color: #2C2C2E;
border-right: 1px solid #38383A;
min-width: 250px;
max-width: 250px;
}
NavigationButton {
background-color: transparent;
border: none;
border-radius: 8px;
padding: 8px 16px;
text-align: left;
font-size: 14px;
color: white;
}
NavigationButton:hover {
background-color: rgba(255, 255, 255, 0.1);
}
NavigationButton:checked {
background-color: rgba(255, 255, 255, 0.15);
font-weight: bold;
}
/* Страницы */
BasePage {
background-color: #1C1C1E;
padding: 16px;
}
/* Заголовки */
QLabel[heading="true"] {
color: white;
font-size: 24px;
font-weight: bold;
margin-bottom: 16px;
}
/* Поля ввода */
QLineEdit, QTextEdit {
background-color: #2C2C2E;
border: 1px solid #38383A;
border-radius: 8px;
padding: 8px 12px;
color: white;
font-size: 14px;
}
QLineEdit:focus, QTextEdit:focus {
border: 2px solid #007AFF;
background-color: #1C1C1E;
}
/* Кнопки */
QPushButton {
background-color: #007AFF;
color: white;
border: none;
border-radius: 8px;
padding: 8px 16px;
font-weight: 500;
font-size: 14px;
min-width: 100px;
min-height: 36px;
}
QPushButton:hover {
background-color: #5856D6;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
QPushButton:pressed {
background-color: #007AFF;
transform: translateY(1px);
}
QPushButton:disabled {
background-color: #38383A;
color: #EBEBF5;
}
/* Выпадающие списки */
QComboBox {
background-color: #2C2C2E;
color: white;
border: 1px solid #38383A;
border-radius: 8px;
padding: 8px 12px;
font-size: 14px;
min-height: 36px;
}
QComboBox::drop-down {
border: none;
width: 20px;
}
QComboBox::down-arrow {
image: url(resources/icons/chevron-down.svg);
width: 12px;
height: 12px;
}
/* Полосы прокрутки */
QScrollBar:vertical {
background: #1C1C1E;
width: 8px;
margin: 0;
}
QScrollBar::handle:vertical {
background: #38383A;
border-radius: 4px;
min-height: 30px;
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical {
height: 0;
}
/* Секции настроек */
SettingsSection {
background-color: #2C2C2E;
border: 1px solid #38383A;
border-radius: 12px;
padding: 16px;
margin-bottom: 16px;
}
/* Списки */
QListWidget {
background-color: #2C2C2E;
border: 1px solid #38383A;
border-radius: 8px;
padding: 8px;
}
QListWidget::item {
background-color: transparent;
border-radius: 4px;
margin: 2px 0;
color: white;
}
QListWidget::item:selected {
background-color: #007AFF;
}
/* Прогресс бар */
QProgressBar {
border: 1px solid #38383A;
border-radius: 4px;
text-align: center;
color: white;
background-color: #2C2C2E;
}
QProgressBar::chunk {
background-color: #007AFF;
border-radius: 3px;
}
+112
View File
@@ -0,0 +1,112 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QLabel, QFrame)
from PyQt6.QtCore import Qt, QPropertyAnimation, QEasingCurve, pyqtSignal
from .icons import IconManager, IconType
from .theme import Theme, Colors, Spacing
from .theme_manager import ThemeManager
class NavigationButton(QPushButton):
def __init__(self, icon_type: IconType, text: str, parent=None):
super().__init__(parent)
self.icon_manager = IconManager.get_instance()
self.icon_type = icon_type
self.setup_ui(text)
def setup_ui(self, text: str):
self.icon_manager = IconManager.get_instance()
self.setIcon(self.icon_manager.get_icon(self.icon_type))
self.setText(text)
self.setCheckable(True)
self.setFixedHeight(40)
self.setStyleSheet("""
QPushButton {
background-color: transparent;
border: none;
border-radius: 8px;
padding: 8px 16px;
text-align: left;
font-size: 14px;
}
QPushButton:hover {
background-color: rgba(255, 255, 255, 0.1);
}
QPushButton:checked {
background-color: rgba(255, 255, 255, 0.15);
font-weight: bold;
}
""")
class NavigationPanel(QFrame):
page_changed = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_ui()
def setup_ui(self):
colors = self.theme_manager.current_theme.get_colors()
self.setStyleSheet(f"""
QFrame {{
background-color: {colors['surface']};
border-right: 1px solid {colors['border']};
}}
""")
# Основной layout
layout = QVBoxLayout(self)
layout.setContentsMargins(8, 16, 8, 16)
layout.setSpacing(8)
# Заголовок
header = QLabel("Stable Diffusion UI")
header.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 18px;
font-weight: bold;
padding: 16px;
}}
""")
layout.addWidget(header)
# Кнопки навигации
self.home_btn = NavigationButton(IconType.HOME, "Главная")
self.models_btn = NavigationButton(IconType.IMAGE, "Модели")
self.settings_btn = NavigationButton(IconType.SETTINGS, "Настройки")
# Добавляем кнопки
layout.addWidget(self.home_btn)
layout.addWidget(self.models_btn)
layout.addWidget(self.settings_btn)
# Растягиваем пространство
layout.addStretch()
# Подключаем сигналы
self.home_btn.clicked.connect(lambda: self.change_page("home"))
self.models_btn.clicked.connect(lambda: self.change_page("models"))
self.settings_btn.clicked.connect(lambda: self.change_page("settings"))
# Устанавливаем фиксированную ширину
self.setFixedWidth(250)
def change_page(self, page_name: str):
"""Смена активной страницы"""
# Отключаем все кнопки
for btn in self.findChildren(NavigationButton):
btn.setChecked(False)
# Включаем нужную кнопку
if page_name == "home":
self.home_btn.setChecked(True)
elif page_name == "models":
self.models_btn.setChecked(True)
elif page_name == "settings":
self.settings_btn.setChecked(True)
# Отправляем сигнал о смене страницы
self.page_changed.emit(page_name)
+130
View File
@@ -0,0 +1,130 @@
from PyQt6.QtWidgets import QWidget, QStackedWidget, QVBoxLayout
from PyQt6.QtCore import QPropertyAnimation, QParallelAnimationGroup, QEasingCurve, Qt, QPoint
from .theme import Theme, Colors
from .theme_manager import ThemeManager
from .style_constants import StyleConstants
class BasePage(QWidget):
"""Базовый класс для страниц"""
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_base_ui()
def setup_base_ui(self):
"""Настройка базового UI"""
colors = self.theme_manager.current_theme.get_colors()
self.setStyleSheet(f"""
QWidget {{
background-color: {colors['background']};
}}
""")
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.setSpacing(0)
# Создаем анимации
self.enter_animation = QPropertyAnimation(self, b"pos")
self.enter_animation.setDuration(250)
self.enter_animation.setEasingCurve(QEasingCurve.Type.OutCubic)
self.exit_animation = QPropertyAnimation(self, b"pos")
self.exit_animation.setDuration(250)
self.exit_animation.setEasingCurve(QEasingCurve.Type.OutCubic)
def enter_animation(self):
"""Анимация появления страницы"""
# Создаем группу анимаций
self.anim_group = QParallelAnimationGroup()
# Анимация прозрачности
fade_anim = QPropertyAnimation(self, b"windowOpacity")
fade_anim.setStartValue(0.0)
fade_anim.setEndValue(1.0)
fade_anim.setDuration(200)
fade_anim.setEasingCurve(QEasingCurve.Type.OutCubic)
# Анимация сдвига
pos_anim = QPropertyAnimation(self, b"pos")
start_pos = self.pos()
pos_anim.setStartValue(start_pos + QPoint(20, 0))
pos_anim.setEndValue(start_pos)
pos_anim.setDuration(200)
pos_anim.setEasingCurve(QEasingCurve.Type.OutCubic)
# Добавляем анимации в группу
self.anim_group.addAnimation(fade_anim)
self.anim_group.addAnimation(pos_anim)
# Запускаем анимацию
self.anim_group.start()
def leave_animation(self):
"""Анимация исчезновения страницы"""
# Создаем группу анимаций
self.anim_group = QParallelAnimationGroup()
# Анимация прозрачности
fade_anim = QPropertyAnimation(self, b"windowOpacity")
fade_anim.setStartValue(1.0)
fade_anim.setEndValue(0.0)
fade_anim.setDuration(200)
fade_anim.setEasingCurve(QEasingCurve.Type.InCubic)
# Анимация сдвига
pos_anim = QPropertyAnimation(self, b"pos")
start_pos = self.pos()
pos_anim.setStartValue(start_pos)
pos_anim.setEndValue(start_pos - QPoint(20, 0))
pos_anim.setDuration(200)
pos_anim.setEasingCurve(QEasingCurve.Type.InCubic)
# Добавляем анимации в группу
self.anim_group.addAnimation(fade_anim)
self.anim_group.addAnimation(pos_anim)
# Запускаем анимацию
self.anim_group.start()
class PageContainer(QStackedWidget):
"""Контейнер для страниц с анимацией переходов"""
def __init__(self, parent=None):
super().__init__(parent)
self.pages = {}
self.current_page = None
def add_page(self, name: str, page: BasePage):
"""Добавить страницу"""
self.pages[name] = page
self.addWidget(page)
def show_page(self, name: str):
"""Показать страницу с анимацией"""
if name not in self.pages:
return
next_page = self.pages[name]
if self.current_page == next_page:
return
# Получаем размеры виджета
width = self.width()
# Настраиваем анимации
if self.current_page:
# Анимация выхода текущей страницы
self.current_page.exit_animation.setStartValue(QPoint(0, 0))
self.current_page.exit_animation.setEndValue(QPoint(-width, 0))
self.current_page.exit_animation.start()
# Анимация входа следующей страницы
next_page.move(width, 0)
next_page.enter_animation.setStartValue(QPoint(width, 0))
next_page.enter_animation.setEndValue(QPoint(0, 0))
next_page.enter_animation.start()
# Показываем страницу
self.setCurrentWidget(next_page)
self.current_page = next_page
+181
View File
@@ -0,0 +1,181 @@
from typing import Dict
class StyleConstants:
# Цветовая схема
COLORS = {
'primary': '#7E57C2', # Основной цвет
'secondary': '#B39DDB', # Вторичный цвет
'accent': '#536DFE', # Акцентный цвет
'success': '#66BB6A', # Цвет успеха
'warning': '#FFA726', # Цвет предупреждения
'error': '#EF5350', # Цвет ошибки
# Светлая тема
'light': {
'background': 'qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FFFFFF, stop:1 #F5F5F5)',
'surface': '#FFFFFF',
'text': '#212121',
'text_secondary': '#757575',
'border': '#E0E0E0',
'hover': '#F5F5F5',
'pressed': '#EEEEEE'
},
# Темная тема
'dark': {
'background': 'qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #1A1A1A, stop:1 #2D2D2D)',
'surface': '#2D2D2D',
'text': '#FFFFFF',
'text_secondary': '#B0B0B0',
'border': '#404040',
'hover': '#353535',
'pressed': '#404040'
}
}
# Размеры и отступы (в пикселях)
SPACING = {
'xxs': 4,
'xs': 8,
'sm': 12,
'md': 16,
'lg': 24,
'xl': 32,
'xxl': 48
}
# Радиусы скругления (в пикселях)
RADIUS = {
'sm': 4,
'md': 8,
'lg': 12,
'xl': 16,
'pill': 9999
}
# Тени
SHADOWS = {
'sm': '0 2px 4px rgba(0,0,0,0.1)',
'md': '0 4px 8px rgba(0,0,0,0.1)',
'lg': '0 8px 16px rgba(0,0,0,0.1)'
}
# Анимации
ANIMATIONS = {
'duration': {
'fast': 150,
'normal': 250,
'slow': 350
},
'easing': 'cubic-bezier(0.4, 0, 0.2, 1)'
}
# Шрифты
FONTS = {
'family': {
'primary': 'Inter',
'secondary': 'Roboto'
},
'size': {
'xs': '12px',
'sm': '14px',
'md': '16px',
'lg': '18px',
'xl': '24px',
'xxl': '32px'
},
'weight': {
'regular': '400',
'medium': '500',
'semibold': '600',
'bold': '700'
}
}
@classmethod
def get_base_styles(cls, theme: str = 'light') -> str:
"""Возвращает базовые стили для приложения"""
colors = cls.COLORS[theme]
return f"""
/* Основные стили */
QMainWindow {{
background: {colors['background']};
}}
QWidget {{
color: {colors['text']};
font-family: {cls.FONTS['family']['primary']};
font-size: {cls.FONTS['size']['md']};
}}
/* Кнопки */
QPushButton {{
background-color: {cls.COLORS['primary']};
color: white;
border: none;
border-radius: {cls.RADIUS['md']}px;
padding: {cls.SPACING['sm']}px {cls.SPACING['md']}px;
font-weight: {cls.FONTS['weight']['medium']};
}}
QPushButton:hover {{
background-color: {cls.COLORS['secondary']};
}}
QPushButton:pressed {{
background-color: {cls.COLORS['accent']};
}}
/* Поля ввода */
QLineEdit, QTextEdit {{
background-color: {colors['surface']};
color: {colors['text']};
border: 1px solid {colors['border']};
border-radius: {cls.RADIUS['md']}px;
padding: {cls.SPACING['sm']}px;
selection-background-color: {cls.COLORS['secondary']};
}}
QLineEdit:focus, QTextEdit:focus {{
border-color: {cls.COLORS['primary']};
}}
/* Выпадающие списки */
QComboBox {{
background-color: {colors['surface']};
color: {colors['text']};
border: 1px solid {colors['border']};
border-radius: {cls.RADIUS['md']}px;
padding: {cls.SPACING['sm']}px;
}}
QComboBox:hover {{
border-color: {cls.COLORS['primary']};
}}
/* Полосы прокрутки */
QScrollBar:vertical {{
background-color: {colors['surface']};
width: 12px;
margin: 0;
}}
QScrollBar::handle:vertical {{
background-color: {cls.COLORS['secondary']};
min-height: 20px;
border-radius: {cls.RADIUS['sm']}px;
}}
QScrollBar:horizontal {{
background-color: {colors['surface']};
height: 12px;
margin: 0;
}}
QScrollBar::handle:horizontal {{
background-color: {cls.COLORS['secondary']};
min-width: 20px;
border-radius: {cls.RADIUS['sm']}px;
}}
"""
+217
View File
@@ -0,0 +1,217 @@
from enum import Enum, auto
from typing import Dict
class Colors:
DARK = {
'background': '#1E1E1E',
'surface': '#252526',
'primary': '#007ACC',
'secondary': '#3C3C3C',
'text': '#FFFFFF',
'text_secondary': '#CCCCCC',
'border': '#3C3C3C',
'hover': '#2A2D2E',
'active': '#37373D',
'error': '#F44336',
'success': '#4CAF50',
'warning': '#FFC107'
}
LIGHT = {
'background': '#FFFFFF',
'surface': '#F3F3F3',
'primary': '#007ACC',
'secondary': '#E0E0E0',
'text': '#000000',
'text_secondary': '#666666',
'border': '#CCCCCC',
'hover': '#E8E8E8',
'active': '#DADADA',
'error': '#F44336',
'success': '#4CAF50',
'warning': '#FFC107'
}
class Fonts:
FAMILY = "Inter"
SIZES = {
"xs": "11px",
"sm": "13px",
"md": "14px",
"lg": "16px",
"xl": "18px"
}
WEIGHTS = {
"normal": "400",
"medium": "500",
"semibold": "600",
"bold": "700"
}
class Spacing:
TINY = 4
SMALL = 8
MEDIUM = 16
LARGE = 24
XLARGE = 32
XXLARGE = 48
class Shadows:
SMALL = {
"dark": "0 2px 4px rgba(0, 0, 0, 0.3)",
"light": "0 2px 4px rgba(0, 0, 0, 0.1)"
}
MEDIUM = {
"dark": "0 4px 8px rgba(0, 0, 0, 0.4)",
"light": "0 4px 8px rgba(0, 0, 0, 0.15)"
}
LARGE = {
"dark": "0 8px 16px rgba(0, 0, 0, 0.5)",
"light": "0 8px 16px rgba(0, 0, 0, 0.2)"
}
class Theme(Enum):
DARK = auto()
LIGHT = auto()
def get_colors(self):
if self == Theme.DARK:
return Colors.DARK
return Colors.LIGHT
def get_spacing(self):
return Spacing
def get_fonts(self):
return Fonts
def get_shadows(self):
if self == Theme.DARK:
return {k: v["dark"] for k, v in Shadows.__dict__.items() if isinstance(v, dict)}
return {k: v["light"] for k, v in Shadows.__dict__.items() if isinstance(v, dict)}
class StyleSheet:
@staticmethod
def get_base_styles(theme: Theme) -> str:
colors = theme.get_colors()
spacing = theme.get_spacing()
return f"""
QMainWindow {{
background-color: {colors['background']};
}}
QWidget {{
color: {colors['text']};
font-family: 'Inter';
}}
QPushButton {{
background-color: {colors['primary']};
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
color: white;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
QLineEdit, QTextEdit {{
background-color: {colors['surface']};
border: 1px solid {colors['border']};
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px;
color: {colors['text']};
}}
QLineEdit:focus, QTextEdit:focus {{
border: 1px solid {colors['primary']};
}}
QComboBox {{
background-color: {colors['surface']};
border: 1px solid {colors['border']};
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px;
color: {colors['text']};
}}
QComboBox:hover {{
border: 1px solid {colors['primary']};
}}
QLabel {{
color: {colors['text']};
}}
QScrollBar:vertical {{
border: none;
background-color: {colors['surface']};
width: 10px;
margin: 0px;
}}
QScrollBar::handle:vertical {{
background-color: {colors['secondary']};
min-height: 20px;
border-radius: 5px;
}}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {{
height: 0px;
}}
QScrollBar:horizontal {{
border: none;
background-color: {colors['surface']};
height: 10px;
margin: 0px;
}}
QScrollBar::handle:horizontal {{
background-color: {colors['secondary']};
min-width: 20px;
border-radius: 5px;
}}
QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {{
width: 0px;
}}
"""
@staticmethod
def get_custom_styles(theme: Theme) -> Dict[str, str]:
colors = theme.get_colors()
return {
"primary_button": f"""
QPushButton {{
background-color: {colors['primary']};
color: white;
}}
""",
"secondary_button": f"""
QPushButton {{
background-color: transparent;
color: {colors['primary']};
border: 1px solid {colors['primary']};
}}
""",
"danger_button": f"""
QPushButton {{
background-color: {colors['error']};
color: white;
}}
""",
"success_button": f"""
QPushButton {{
background-color: {colors['success']};
color: white;
}}
"""
}
+46
View File
@@ -0,0 +1,46 @@
from typing import Optional
from PyQt6.QtWidgets import QApplication
from .theme import Theme, StyleSheet
class ThemeManager:
_instance: Optional['ThemeManager'] = None
_current_theme = Theme.DARK
def __new__(cls):
if cls._instance is None:
cls._instance = super(ThemeManager, cls).__new__(cls)
return cls._instance
@classmethod
def get_instance(cls) -> 'ThemeManager':
if cls._instance is None:
cls._instance = cls()
return cls._instance
@property
def current_theme(self) -> Theme:
return self._current_theme
def switch_theme(self, theme: Theme):
"""Переключение темы приложения"""
self._current_theme = theme
self.apply_theme()
def toggle_theme(self):
"""Переключение между светлой и темной темой"""
new_theme = Theme.LIGHT if self._current_theme == Theme.DARK else Theme.DARK
self.switch_theme(new_theme)
def apply_theme(self):
"""Применение текущей темы ко всему приложению"""
if not QApplication.instance():
return
# Применяем базовые стили
QApplication.instance().setStyleSheet(
StyleSheet.get_base_styles(self._current_theme)
)
def get_style(self, style_name: str) -> str:
"""Получение конкретного стиля"""
return StyleSheet.get_base_styles(self._current_theme)
+91
View File
@@ -0,0 +1,91 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QTextEdit, QComboBox)
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QTextCursor
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
class ConsoleWindow(QWidget):
"""Окно для консольного вывода"""
def __init__(self, parent=None):
super().__init__(parent)
self.icon_manager = IconManager.get_instance()
self.setup_ui()
def setup_ui(self):
self.setWindowTitle("Консоль")
self.resize(600, 400)
# Основной layout
layout = QVBoxLayout(self)
layout.setSpacing(StyleConstants.SPACING['md'])
layout.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
# Верхняя панель
top_panel = QHBoxLayout()
# Уровень логирования
self.log_level = QComboBox()
self.log_level.addItems(["INFO", "WARNING", "ERROR", "DEBUG"])
top_panel.addWidget(self.log_level)
# Кнопки
clear_btn = QPushButton("Очистить")
clear_btn.setIcon(self.icon_manager.get_icon(IconType.DELETE))
clear_btn.clicked.connect(self.clear_console)
top_panel.addWidget(clear_btn)
save_btn = QPushButton("Сохранить")
save_btn.setIcon(self.icon_manager.get_icon(IconType.SAVE))
top_panel.addWidget(save_btn)
top_panel.addStretch()
layout.addLayout(top_panel)
# Консоль
self.console = QTextEdit()
self.console.setReadOnly(True)
self.console.setStyleSheet(f"""
QTextEdit {{
background-color: {StyleConstants.COLORS['dark']['background']};
color: {StyleConstants.COLORS['dark']['text']};
font-family: 'Consolas', monospace;
font-size: {StyleConstants.FONTS['size']['md']};
padding: {StyleConstants.SPACING['md']}px;
border-radius: {StyleConstants.RADIUS['md']}px;
}}
""")
layout.addWidget(self.console)
# Применяем стили
self.setStyleSheet(StyleConstants.get_base_styles('light'))
def log(self, message: str, level: str = "INFO"):
"""Добавление сообщения в консоль"""
color = {
"INFO": StyleConstants.COLORS['primary'],
"WARNING": StyleConstants.COLORS['warning'],
"ERROR": StyleConstants.COLORS['error'],
"DEBUG": StyleConstants.COLORS['secondary']
}.get(level, StyleConstants.COLORS['primary'])
# Форматируем сообщение
formatted_message = f'<span style="color: {color}">[{level}]</span> {message}<br>'
# Добавляем сообщение в консоль
cursor = self.console.textCursor()
cursor.movePosition(QTextCursor.MoveOperation.End)
cursor.insertHtml(formatted_message)
# Прокручиваем к последнему сообщению
self.console.setTextCursor(cursor)
self.console.ensureCursorVisible()
def clear_console(self):
"""Очистка консоли"""
self.console.clear()
+153
View File
@@ -0,0 +1,153 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QTextEdit, QComboBox,
QScrollArea, QFrame, QCheckBox)
from PyQt6.QtCore import Qt, pyqtSignal
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
class NegativePromptCategory(QFrame):
"""Виджет категории негативных промптов"""
def __init__(self, title: str, prompts: dict, parent=None):
super().__init__(parent)
self.title = title
self.prompts = prompts
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Заголовок категории
title_label = QLabel(self.title)
title_label.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['lg']};
font-weight: {StyleConstants.FONTS['weight']['bold']};
margin-bottom: {StyleConstants.SPACING['sm']};
""")
layout.addWidget(title_label)
# Список промптов с чекбоксами
for prompt, description in self.prompts.items():
prompt_frame = QFrame()
prompt_layout = QVBoxLayout(prompt_frame)
checkbox = QCheckBox(prompt)
checkbox.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['md']};
font-weight: {StyleConstants.FONTS['weight']['medium']};
""")
description_label = QLabel(description)
description_label.setStyleSheet(f"""
color: {StyleConstants.COLORS['light']['text_secondary']};
font-size: {StyleConstants.FONTS['size']['sm']};
""")
description_label.setWordWrap(True)
prompt_layout.addWidget(checkbox)
prompt_layout.addWidget(description_label)
layout.addWidget(prompt_frame)
self.setStyleSheet(f"""
QFrame {{
background-color: {StyleConstants.COLORS['light']['surface']};
border-radius: {StyleConstants.RADIUS['lg']};
padding: {StyleConstants.SPACING['md']};
margin-bottom: {StyleConstants.SPACING['md']};
}}
""")
class NegativePromptWindow(QWidget):
"""Окно для работы с негативными промптами"""
prompts_selected = pyqtSignal(list)
def __init__(self, parent=None):
super().__init__(parent)
self.icon_manager = IconManager.get_instance()
self.setup_ui()
def setup_ui(self):
self.setWindowTitle("Негативные промпты")
self.resize(800, 600)
# Основной layout
layout = QVBoxLayout(self)
layout.setSpacing(StyleConstants.SPACING['md'])
layout.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
# Верхняя панель
top_panel = QHBoxLayout()
# Поиск
self.search_box = QComboBox()
self.search_box.setEditable(True)
self.search_box.setPlaceholderText("Поиск негативных промптов...")
self.search_box.setMinimumWidth(300)
top_panel.addWidget(self.search_box)
# Кнопки
select_all_btn = QPushButton("Выбрать все")
select_all_btn.setIcon(self.icon_manager.get_icon(IconType.SUCCESS))
top_panel.addWidget(select_all_btn)
clear_btn = QPushButton("Очистить")
clear_btn.setIcon(self.icon_manager.get_icon(IconType.CLOSE))
top_panel.addWidget(clear_btn)
top_panel.addStretch()
layout.addLayout(top_panel)
# Область прокрутки для категорий
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# Контейнер для категорий
categories_widget = QWidget()
self.categories_layout = QVBoxLayout(categories_widget)
# Добавляем тестовые категории
test_categories = {
"Качество": {
"Низкое качество": "Удаляет артефакты низкого качества и размытость",
"Шум и зернистость": "Убирает нежелательный шум и зернистость",
"Искажения": "Предотвращает искажения пропорций и перспективы"
},
"Артефакты": {
"Двойные элементы": "Убирает дублирование частей изображения",
"Размытые лица": "Улучшает четкость и детализацию лиц",
"Неправильная анатомия": "Корректирует анатомические ошибки"
}
}
for title, prompts in test_categories.items():
category = NegativePromptCategory(title, prompts)
self.categories_layout.addWidget(category)
self.categories_layout.addStretch()
scroll_area.setWidget(categories_widget)
layout.addWidget(scroll_area)
# Нижняя панель
bottom_panel = QHBoxLayout()
apply_btn = QPushButton("Применить")
apply_btn.setIcon(self.icon_manager.get_icon(IconType.SUCCESS))
apply_btn.setStyleSheet(f"""
background-color: {StyleConstants.COLORS['success']};
""")
bottom_panel.addWidget(apply_btn)
cancel_btn = QPushButton("Отмена")
cancel_btn.setIcon(self.icon_manager.get_icon(IconType.CLOSE))
bottom_panel.addWidget(cancel_btn)
bottom_panel.addStretch()
layout.addLayout(bottom_panel)
# Применяем стили
self.setStyleSheet(StyleConstants.get_base_styles('light'))
+117
View File
@@ -0,0 +1,117 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QTextEdit, QComboBox,
QScrollArea, QFrame)
from PyQt6.QtCore import Qt, pyqtSignal
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
class PromptCategory(QFrame):
"""Виджет категории промптов"""
def __init__(self, title: str, prompts: list, parent=None):
super().__init__(parent)
self.title = title
self.prompts = prompts
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Заголовок категории
title_label = QLabel(self.title)
title_label.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['lg']};
font-weight: {StyleConstants.FONTS['weight']['bold']};
margin-bottom: {StyleConstants.SPACING['sm']};
""")
layout.addWidget(title_label)
# Список промптов
for prompt in self.prompts:
btn = QPushButton(prompt)
btn.setStyleSheet(f"""
text-align: left;
padding: {StyleConstants.SPACING['sm']};
margin-bottom: {StyleConstants.SPACING['xs']};
""")
layout.addWidget(btn)
self.setStyleSheet(f"""
QFrame {{
background-color: {StyleConstants.COLORS['light']['surface']};
border-radius: {StyleConstants.RADIUS['lg']};
padding: {StyleConstants.SPACING['md']};
margin-bottom: {StyleConstants.SPACING['md']};
}}
""")
class PromptWindow(QWidget):
"""Окно для работы с промптами"""
prompt_selected = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.icon_manager = IconManager.get_instance()
self.setup_ui()
def setup_ui(self):
self.setWindowTitle("Библиотека промптов")
self.resize(800, 600)
# Основной layout
layout = QVBoxLayout(self)
layout.setSpacing(StyleConstants.SPACING['md'])
layout.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
# Верхняя панель
top_panel = QHBoxLayout()
# Поиск
self.search_box = QComboBox()
self.search_box.setEditable(True)
self.search_box.setPlaceholderText("Поиск промптов...")
self.search_box.setMinimumWidth(300)
top_panel.addWidget(self.search_box)
# Кнопки
add_btn = QPushButton("Добавить промпт")
add_btn.setIcon(self.icon_manager.get_icon(IconType.ADD))
top_panel.addWidget(add_btn)
refresh_btn = QPushButton("Обновить")
refresh_btn.setIcon(self.icon_manager.get_icon(IconType.REFRESH))
top_panel.addWidget(refresh_btn)
top_panel.addStretch()
layout.addLayout(top_panel)
# Область прокрутки для категорий
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# Контейнер для категорий
categories_widget = QWidget()
self.categories_layout = QVBoxLayout(categories_widget)
# Добавляем тестовые категории
test_categories = {
"Стили": ["Фотореалистичный", "Аниме", "Масляная живопись", "Акварель"],
"Освещение": ["Дневной свет", "Закат", "Ночное освещение", "Студийный свет"],
"Композиция": ["Крупный план", "Панорама", "Портрет", "Пейзаж"]
}
for title, prompts in test_categories.items():
category = PromptCategory(title, prompts)
self.categories_layout.addWidget(category)
self.categories_layout.addStretch()
scroll_area.setWidget(categories_widget)
layout.addWidget(scroll_area)
# Применяем стили
self.setStyleSheet(StyleConstants.get_base_styles('light'))
+14
View File
@@ -0,0 +1,14 @@
# requirements.txt
certifi==2025.1.31
charset-normalizer==3.4.1
dotenv==0.9.9
idna==3.10
pillow==11.1.0
PyQt6==6.8.1
PyQt6-Qt6==6.8.2
PyQt6_sip==13.10.0
python-dotenv==1.0.1
requests==2.32.3
urllib3==2.3.0
websockets==15.0.1
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"/></svg>

After

Width:  |  Height:  |  Size: 156 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z"/></svg>

After

Width:  |  Height:  |  Size: 224 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M19 4h-3.5l-1-1h-5l-1 1H5v2h14M6 19a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7H6z"/></svg>

After

Width:  |  Height:  |  Size: 193 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M18 15v3h-3v2h3v3h2v-3h3v-2h-3v-3zm-4.7 6H5c-1.1 0-2-.9-2-2V5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2v8.3c-.6-.2-1.3-.3-2-.3c-1.1 0-2.2.3-3.1.9L14.5 12L11 16.5l-2.5-3L5 18h8.1c-.1.3-.1.7-.1 1c0 .7.1 1.4.3 2"/></svg>

After

Width:  |  Height:  |  Size: 321 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8z"/></svg>

After

Width:  |  Height:  |  Size: 158 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="m8.5 13.5l2.5 3l3.5-4.5l4.5 6H5m16 1V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2"/></svg>

After

Width:  |  Height:  |  Size: 225 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M21 16.5c0 .38-.21.71-.53.88l-7.9 4.44c-.16.12-.36.18-.57.18s-.41-.06-.57-.18l-7.9-4.44A.99.99 0 0 1 3 16.5v-9c0-.38.21-.71.53-.88l7.9-4.44c.16-.12.36-.18.57-.18s.41.06.57.18l7.9 4.44c.32.17.53.5.53.88zM12 4.15L6.04 7.5L12 10.85l5.96-3.35z"/></svg>

After

Width:  |  Height:  |  Size: 362 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M17.65 6.35A7.96 7.96 0 0 0 12 4a8 8 0 0 0-8 8a8 8 0 0 0 8 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18a6 6 0 0 1-6-6a6 6 0 0 1 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4z"/></svg>

After

Width:  |  Height:  |  Size: 299 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M15 9H5V5h10m-3 14a3 3 0 0 1-3-3a3 3 0 0 1 3-3a3 3 0 0 1 3 3a3 3 0 0 1-3 3m5-16H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V7z"/></svg>

After

Width:  |  Height:  |  Size: 255 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M12 15.5A3.5 3.5 0 0 1 8.5 12A3.5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5a3.5 3.5 0 0 1-3.5 3.5m7.43-2.53c.04-.32.07-.64.07-.97s-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.31-.61-.22l-2.49 1c-.52-.39-1.06-.73-1.69-.98l-.37-2.65A.506.506 0 0 0 14 2h-4c-.25 0-.46.18-.5.42l-.37 2.65c-.63.25-1.17.59-1.69.98l-2.49-1c-.22-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 1s.03.65.07.97l-2.11 1.66c-.19.15-.25.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.06.74 1.69.99l.37 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.63-.26 1.17-.59 1.69-.99l2.49 1.01c.22.08.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64z"/></svg>

After

Width:  |  Height:  |  Size: 787 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10s10-4.5 10-10S17.5 2 12 2m-2 15l-5-5l1.41-1.41L10 14.17l7.59-7.59L19 8z"/></svg>

After

Width:  |  Height:  |  Size: 229 B

+51
View File
@@ -0,0 +1,51 @@
import requests
from pathlib import Path
import os
def download_file(url: str, path: Path):
"""Загрузка файла по URL"""
try:
response = requests.get(url)
response.raise_for_status()
path.write_bytes(response.content)
print(f"Загружен файл: {path}")
except Exception as e:
print(f"Ошибка при загрузке {path}: {e}")
def download_font():
"""Загрузка шрифта Inter"""
fonts_dir = Path("resources/fonts")
fonts_dir.mkdir(parents=True, exist_ok=True)
font_url = "https://github.com/rsms/inter/raw/master/docs/font-files/InterVariable.ttf"
font_path = fonts_dir / "InterVariable.ttf"
if not font_path.exists():
download_file(font_url, font_path)
def download_icons():
"""Загрузка иконок"""
icons_dir = Path("resources/icons")
icons_dir.mkdir(parents=True, exist_ok=True)
icons = {
"home.svg": "https://api.iconify.design/mdi/home.svg",
"models.svg": "https://api.iconify.design/mdi/cube.svg",
"settings.svg": "https://api.iconify.design/mdi/cog.svg",
"generate.svg": "https://api.iconify.design/mdi/image-plus.svg",
"add.svg": "https://api.iconify.design/mdi/plus.svg",
"delete.svg": "https://api.iconify.design/mdi/delete.svg",
"refresh.svg": "https://api.iconify.design/mdi/refresh.svg",
"save.svg": "https://api.iconify.design/mdi/content-save.svg",
"close.svg": "https://api.iconify.design/mdi/close.svg",
"success.svg": "https://api.iconify.design/mdi/check-circle.svg",
}
for filename, url in icons.items():
icon_path = icons_dir / filename
if not icon_path.exists():
download_file(url, icon_path)
if __name__ == "__main__":
download_font()
download_icons()
+49 -56
View File
@@ -6,95 +6,88 @@ const app = express();
const port = 3000; const port = 3000;
// Конфигурация API Stable Diffusion // Конфигурация API Stable Diffusion
const SD_API_URL = 'http://localhost:7860'; const SD_API_URL = process.env.SD_API_URL || 'http://localhost:7860';
app.use(cors()); app.use(cors());
app.use(express.json()); app.use(express.json());
// Прокси для txt2img с отслеживанием прогресса // Middleware для логирования запросов
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next();
});
// Прокси для txt2img
app.post('/api/txt2img', async (req, res) => { app.post('/api/txt2img', async (req, res) => {
try { try {
// Отправляем запрос на генерацию const response = await axios.post(`${SD_API_URL}/sdapi/v1/txt2img`, req.body);
const generationPromise = axios.post(`${SD_API_URL}/sdapi/v1/txt2img`, req.body);
// Начинаем отслеживать прогресс сразу
let isGenerating = true;
let lastProgress = 0;
while (isGenerating) {
try {
const progressResponse = await axios.get(`${SD_API_URL}/sdapi/v1/progress`);
const progress = progressResponse.data;
if (progress.progress >= 1.0) {
isGenerating = false;
}
// Если прогресс изменился, обновляем lastProgress
if (progress.progress !== lastProgress) {
lastProgress = progress.progress;
console.log(`Прогресс генерации: ${Math.round(progress.progress * 100)}%`);
}
await new Promise(resolve => setTimeout(resolve, 100));
} catch (error) {
console.error('Ошибка при получении прогресса:', error);
break;
}
}
// Ждем завершения генерации
const response = await generationPromise;
res.json(response.data); res.json(response.data);
} catch (error) { } catch (error) {
console.error('Ошибка при запросе к Stable Diffusion API:', error); console.error('Ошибка при запросе к Stable Diffusion API:', error);
res.status(500).json({ error: 'Ошибка при генерации изображения' }); res.status(500).json({
error: 'Ошибка при генерации изображения',
details: error.message
});
} }
}); });
// Прокси для проверки прогресса // Прокси для получения прогресса
app.get('/api/progress', async (req, res) => { app.get('/api/progress', async (req, res) => {
try { try {
const response = await axios.get(`${SD_API_URL}/sdapi/v1/progress`); const response = await axios.get(`${SD_API_URL}/sdapi/v1/progress`);
const progress = response.data; res.json({
...response.data,
// Добавляем дополнительную информацию о прогрессе percentage: Math.round(response.data.progress * 100)
const result = { });
...progress,
percentage: Math.round(progress.progress * 100),
current_step: progress.state?.sampling_step || 0,
total_steps: progress.state?.sampling_steps || 1
};
res.json(result);
} catch (error) { } catch (error) {
console.error('Ошибка при получении прогресса:', error); console.error('Ошибка при получении прогресса:', error);
res.status(500).json({ error: 'Ошибка при получении прогресса' }); res.status(500).json({
error: 'Ошибка при получении прогресса',
details: error.message
});
} }
}); });
// Прокси для получения моделей // Прокси для получения списка моделей
app.get('/api/sd-models', async (req, res) => { app.get('/api/models', async (req, res) => {
try { try {
const response = await axios.get(`${SD_API_URL}/sdapi/v1/sd-models`); const response = await axios.get(`${SD_API_URL}/sdapi/v1/sd-models`);
res.json(response.data); res.json(response.data);
} catch (error) { } catch (error) {
console.error('Ошибка при получении списка моделей:', error); console.error('Ошибка при получении списка моделей:', error);
res.status(500).json({ error: 'Ошибка при получении списка моделей' }); res.status(500).json({
error: 'Ошибка при получении списка моделей',
details: error.message
});
} }
}); });
// Прокси для получения сэмплеров // Прокси для изменения модели
app.get('/api/samplers', async (req, res) => { app.post('/api/models/switch', async (req, res) => {
try { try {
const response = await axios.get(`${SD_API_URL}/sdapi/v1/samplers`); const response = await axios.post(`${SD_API_URL}/sdapi/v1/options`, {
res.json(response.data); sd_model_checkpoint: req.body.model_name
});
res.json({ success: true });
} catch (error) { } catch (error) {
console.error('Ошибка при получении списка сэмплеров:', error); console.error('Ошибка при переключении модели:', error);
res.status(500).json({ error: 'Ошибка при получении списка сэмплеров' }); res.status(500).json({
error: 'Ошибка при переключении модели',
details: error.message
});
} }
}); });
// Обработка ошибок
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
error: 'Внутренняя ошибка сервера',
details: err.message
});
});
app.listen(port, () => { app.listen(port, () => {
console.log(`Сервер запущен на порту ${port}`); console.log(`Сервер запущен на порту ${port}`);
console.log(`Stable Diffusion API URL: ${SD_API_URL}`);
}); });
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Pedro Burón
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,14 @@
Metadata-Version: 2.1
Name: dotenv
Version: 0.9.9
Summary: Deprecated package
Home-page: https://github.com/pedroburon/dotenv
Author: Pedro Burón
Author-email: pedroburonv@gmail.com
License: UNKNOWN
Platform: UNKNOWN
License-File: LICENSE
Requires-Dist: python-dotenv
UNKNOWN
@@ -0,0 +1,7 @@
dotenv-0.9.9.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
dotenv-0.9.9.dist-info/LICENSE,sha256=UDN9gmLB0tw_cK1WQ5POBgI5Iu13Bt4kf9VSMrrjJ7c,1069
dotenv-0.9.9.dist-info/METADATA,sha256=C-L93MBAM6T9nTEUOLcRWO_CuLfoo4Zd9WIpxnMu4e0,279
dotenv-0.9.9.dist-info/RECORD,,
dotenv-0.9.9.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
dotenv-0.9.9.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
dotenv-0.9.9.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
@@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.45.1)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any
@@ -0,0 +1 @@
+49
View File
@@ -0,0 +1,49 @@
from typing import Any, Optional
from .main import (dotenv_values, find_dotenv, get_key, load_dotenv, set_key,
unset_key)
def load_ipython_extension(ipython: Any) -> None:
from .ipython import load_ipython_extension
load_ipython_extension(ipython)
def get_cli_string(
path: Optional[str] = None,
action: Optional[str] = None,
key: Optional[str] = None,
value: Optional[str] = None,
quote: Optional[str] = None,
):
"""Returns a string suitable for running as a shell script.
Useful for converting a arguments passed to a fabric task
to be passed to a `local` or `run` command.
"""
command = ['dotenv']
if quote:
command.append(f'-q {quote}')
if path:
command.append(f'-f {path}')
if action:
command.append(action)
if key:
command.append(key)
if value:
if ' ' in value:
command.append(f'"{value}"')
else:
command.append(value)
return ' '.join(command).strip()
__all__ = ['get_cli_string',
'load_dotenv',
'dotenv_values',
'get_key',
'set_key',
'unset_key',
'find_dotenv',
'load_ipython_extension']
@@ -0,0 +1,6 @@
"""Entry point for cli, enables execution with `python -m dotenv`"""
from .cli import cli
if __name__ == "__main__":
cli()
+199
View File
@@ -0,0 +1,199 @@
import json
import os
import shlex
import sys
from contextlib import contextmanager
from subprocess import Popen
from typing import Any, Dict, IO, Iterator, List
try:
import click
except ImportError:
sys.stderr.write('It seems python-dotenv is not installed with cli option. \n'
'Run pip install "python-dotenv[cli]" to fix this.')
sys.exit(1)
from .main import dotenv_values, set_key, unset_key
from .version import __version__
def enumerate_env():
"""
Return a path for the ${pwd}/.env file.
If pwd does not exist, return None.
"""
try:
cwd = os.getcwd()
except FileNotFoundError:
return None
path = os.path.join(cwd, '.env')
return path
@click.group()
@click.option('-f', '--file', default=enumerate_env(),
type=click.Path(file_okay=True),
help="Location of the .env file, defaults to .env file in current working directory.")
@click.option('-q', '--quote', default='always',
type=click.Choice(['always', 'never', 'auto']),
help="Whether to quote or not the variable values. Default mode is always. This does not affect parsing.")
@click.option('-e', '--export', default=False,
type=click.BOOL,
help="Whether to write the dot file as an executable bash script.")
@click.version_option(version=__version__)
@click.pass_context
def cli(ctx: click.Context, file: Any, quote: Any, export: Any) -> None:
"""This script is used to set, get or unset values from a .env file."""
ctx.obj = {'QUOTE': quote, 'EXPORT': export, 'FILE': file}
@contextmanager
def stream_file(path: os.PathLike) -> Iterator[IO[str]]:
"""
Open a file and yield the corresponding (decoded) stream.
Exits with error code 2 if the file cannot be opened.
"""
try:
with open(path) as stream:
yield stream
except OSError as exc:
print(f"Error opening env file: {exc}", file=sys.stderr)
exit(2)
@cli.command()
@click.pass_context
@click.option('--format', default='simple',
type=click.Choice(['simple', 'json', 'shell', 'export']),
help="The format in which to display the list. Default format is simple, "
"which displays name=value without quotes.")
def list(ctx: click.Context, format: bool) -> None:
"""Display all the stored key/value."""
file = ctx.obj['FILE']
with stream_file(file) as stream:
values = dotenv_values(stream=stream)
if format == 'json':
click.echo(json.dumps(values, indent=2, sort_keys=True))
else:
prefix = 'export ' if format == 'export' else ''
for k in sorted(values):
v = values[k]
if v is not None:
if format in ('export', 'shell'):
v = shlex.quote(v)
click.echo(f'{prefix}{k}={v}')
@cli.command()
@click.pass_context
@click.argument('key', required=True)
@click.argument('value', required=True)
def set(ctx: click.Context, key: Any, value: Any) -> None:
"""Store the given key/value."""
file = ctx.obj['FILE']
quote = ctx.obj['QUOTE']
export = ctx.obj['EXPORT']
success, key, value = set_key(file, key, value, quote, export)
if success:
click.echo(f'{key}={value}')
else:
exit(1)
@cli.command()
@click.pass_context
@click.argument('key', required=True)
def get(ctx: click.Context, key: Any) -> None:
"""Retrieve the value for the given key."""
file = ctx.obj['FILE']
with stream_file(file) as stream:
values = dotenv_values(stream=stream)
stored_value = values.get(key)
if stored_value:
click.echo(stored_value)
else:
exit(1)
@cli.command()
@click.pass_context
@click.argument('key', required=True)
def unset(ctx: click.Context, key: Any) -> None:
"""Removes the given key."""
file = ctx.obj['FILE']
quote = ctx.obj['QUOTE']
success, key = unset_key(file, key, quote)
if success:
click.echo(f"Successfully removed {key}")
else:
exit(1)
@cli.command(context_settings={'ignore_unknown_options': True})
@click.pass_context
@click.option(
"--override/--no-override",
default=True,
help="Override variables from the environment file with those from the .env file.",
)
@click.argument('commandline', nargs=-1, type=click.UNPROCESSED)
def run(ctx: click.Context, override: bool, commandline: List[str]) -> None:
"""Run command with environment variables present."""
file = ctx.obj['FILE']
if not os.path.isfile(file):
raise click.BadParameter(
f'Invalid value for \'-f\' "{file}" does not exist.',
ctx=ctx
)
dotenv_as_dict = {
k: v
for (k, v) in dotenv_values(file).items()
if v is not None and (override or k not in os.environ)
}
if not commandline:
click.echo('No command given.')
exit(1)
ret = run_command(commandline, dotenv_as_dict)
exit(ret)
def run_command(command: List[str], env: Dict[str, str]) -> int:
"""Run command in sub process.
Runs the command in a sub process with the variables from `env`
added in the current environment variables.
Parameters
----------
command: List[str]
The command and it's parameters
env: Dict
The additional environment variables
Returns
-------
int
The return code of the command
"""
# copy the current environment variables and add the vales from
# `env`
cmd_env = os.environ.copy()
cmd_env.update(env)
p = Popen(command,
universal_newlines=True,
bufsize=0,
shell=False,
env=cmd_env)
_, _ = p.communicate()
return p.returncode
+39
View File
@@ -0,0 +1,39 @@
from IPython.core.magic import Magics, line_magic, magics_class # type: ignore
from IPython.core.magic_arguments import (argument, magic_arguments, # type: ignore
parse_argstring) # type: ignore
from .main import find_dotenv, load_dotenv
@magics_class
class IPythonDotEnv(Magics):
@magic_arguments()
@argument(
'-o', '--override', action='store_true',
help="Indicate to override existing variables"
)
@argument(
'-v', '--verbose', action='store_true',
help="Indicate function calls to be verbose"
)
@argument('dotenv_path', nargs='?', type=str, default='.env',
help='Search in increasingly higher folders for the `dotenv_path`')
@line_magic
def dotenv(self, line):
args = parse_argstring(self.dotenv, line)
# Locate the .env file
dotenv_path = args.dotenv_path
try:
dotenv_path = find_dotenv(dotenv_path, True, True)
except IOError:
print("cannot find .env file")
return
# Load the .env file
load_dotenv(dotenv_path, verbose=args.verbose, override=args.override)
def load_ipython_extension(ipython):
"""Register the %dotenv magic."""
ipython.register_magics(IPythonDotEnv)
+392
View File
@@ -0,0 +1,392 @@
import io
import logging
import os
import pathlib
import shutil
import sys
import tempfile
from collections import OrderedDict
from contextlib import contextmanager
from typing import (IO, Dict, Iterable, Iterator, Mapping, Optional, Tuple,
Union)
from .parser import Binding, parse_stream
from .variables import parse_variables
# A type alias for a string path to be used for the paths in this file.
# These paths may flow to `open()` and `shutil.move()`; `shutil.move()`
# only accepts string paths, not byte paths or file descriptors. See
# https://github.com/python/typeshed/pull/6832.
StrPath = Union[str, 'os.PathLike[str]']
logger = logging.getLogger(__name__)
def with_warn_for_invalid_lines(mappings: Iterator[Binding]) -> Iterator[Binding]:
for mapping in mappings:
if mapping.error:
logger.warning(
"Python-dotenv could not parse statement starting at line %s",
mapping.original.line,
)
yield mapping
class DotEnv:
def __init__(
self,
dotenv_path: Optional[StrPath],
stream: Optional[IO[str]] = None,
verbose: bool = False,
encoding: Optional[str] = None,
interpolate: bool = True,
override: bool = True,
) -> None:
self.dotenv_path: Optional[StrPath] = dotenv_path
self.stream: Optional[IO[str]] = stream
self._dict: Optional[Dict[str, Optional[str]]] = None
self.verbose: bool = verbose
self.encoding: Optional[str] = encoding
self.interpolate: bool = interpolate
self.override: bool = override
@contextmanager
def _get_stream(self) -> Iterator[IO[str]]:
if self.dotenv_path and os.path.isfile(self.dotenv_path):
with open(self.dotenv_path, encoding=self.encoding) as stream:
yield stream
elif self.stream is not None:
yield self.stream
else:
if self.verbose:
logger.info(
"Python-dotenv could not find configuration file %s.",
self.dotenv_path or '.env',
)
yield io.StringIO('')
def dict(self) -> Dict[str, Optional[str]]:
"""Return dotenv as dict"""
if self._dict:
return self._dict
raw_values = self.parse()
if self.interpolate:
self._dict = OrderedDict(resolve_variables(raw_values, override=self.override))
else:
self._dict = OrderedDict(raw_values)
return self._dict
def parse(self) -> Iterator[Tuple[str, Optional[str]]]:
with self._get_stream() as stream:
for mapping in with_warn_for_invalid_lines(parse_stream(stream)):
if mapping.key is not None:
yield mapping.key, mapping.value
def set_as_environment_variables(self) -> bool:
"""
Load the current dotenv as system environment variable.
"""
if not self.dict():
return False
for k, v in self.dict().items():
if k in os.environ and not self.override:
continue
if v is not None:
os.environ[k] = v
return True
def get(self, key: str) -> Optional[str]:
"""
"""
data = self.dict()
if key in data:
return data[key]
if self.verbose:
logger.warning("Key %s not found in %s.", key, self.dotenv_path)
return None
def get_key(
dotenv_path: StrPath,
key_to_get: str,
encoding: Optional[str] = "utf-8",
) -> Optional[str]:
"""
Get the value of a given key from the given .env.
Returns `None` if the key isn't found or doesn't have a value.
"""
return DotEnv(dotenv_path, verbose=True, encoding=encoding).get(key_to_get)
@contextmanager
def rewrite(
path: StrPath,
encoding: Optional[str],
) -> Iterator[Tuple[IO[str], IO[str]]]:
pathlib.Path(path).touch()
with tempfile.NamedTemporaryFile(mode="w", encoding=encoding, delete=False) as dest:
error = None
try:
with open(path, encoding=encoding) as source:
yield (source, dest)
except BaseException as err:
error = err
if error is None:
shutil.move(dest.name, path)
else:
os.unlink(dest.name)
raise error from None
def set_key(
dotenv_path: StrPath,
key_to_set: str,
value_to_set: str,
quote_mode: str = "always",
export: bool = False,
encoding: Optional[str] = "utf-8",
) -> Tuple[Optional[bool], str, str]:
"""
Adds or Updates a key/value to the given .env
If the .env path given doesn't exist, fails instead of risking creating
an orphan .env somewhere in the filesystem
"""
if quote_mode not in ("always", "auto", "never"):
raise ValueError(f"Unknown quote_mode: {quote_mode}")
quote = (
quote_mode == "always"
or (quote_mode == "auto" and not value_to_set.isalnum())
)
if quote:
value_out = "'{}'".format(value_to_set.replace("'", "\\'"))
else:
value_out = value_to_set
if export:
line_out = f'export {key_to_set}={value_out}\n'
else:
line_out = f"{key_to_set}={value_out}\n"
with rewrite(dotenv_path, encoding=encoding) as (source, dest):
replaced = False
missing_newline = False
for mapping in with_warn_for_invalid_lines(parse_stream(source)):
if mapping.key == key_to_set:
dest.write(line_out)
replaced = True
else:
dest.write(mapping.original.string)
missing_newline = not mapping.original.string.endswith("\n")
if not replaced:
if missing_newline:
dest.write("\n")
dest.write(line_out)
return True, key_to_set, value_to_set
def unset_key(
dotenv_path: StrPath,
key_to_unset: str,
quote_mode: str = "always",
encoding: Optional[str] = "utf-8",
) -> Tuple[Optional[bool], str]:
"""
Removes a given key from the given `.env` file.
If the .env path given doesn't exist, fails.
If the given key doesn't exist in the .env, fails.
"""
if not os.path.exists(dotenv_path):
logger.warning("Can't delete from %s - it doesn't exist.", dotenv_path)
return None, key_to_unset
removed = False
with rewrite(dotenv_path, encoding=encoding) as (source, dest):
for mapping in with_warn_for_invalid_lines(parse_stream(source)):
if mapping.key == key_to_unset:
removed = True
else:
dest.write(mapping.original.string)
if not removed:
logger.warning("Key %s not removed from %s - key doesn't exist.", key_to_unset, dotenv_path)
return None, key_to_unset
return removed, key_to_unset
def resolve_variables(
values: Iterable[Tuple[str, Optional[str]]],
override: bool,
) -> Mapping[str, Optional[str]]:
new_values: Dict[str, Optional[str]] = {}
for (name, value) in values:
if value is None:
result = None
else:
atoms = parse_variables(value)
env: Dict[str, Optional[str]] = {}
if override:
env.update(os.environ) # type: ignore
env.update(new_values)
else:
env.update(new_values)
env.update(os.environ) # type: ignore
result = "".join(atom.resolve(env) for atom in atoms)
new_values[name] = result
return new_values
def _walk_to_root(path: str) -> Iterator[str]:
"""
Yield directories starting from the given directory up to the root
"""
if not os.path.exists(path):
raise IOError('Starting path not found')
if os.path.isfile(path):
path = os.path.dirname(path)
last_dir = None
current_dir = os.path.abspath(path)
while last_dir != current_dir:
yield current_dir
parent_dir = os.path.abspath(os.path.join(current_dir, os.path.pardir))
last_dir, current_dir = current_dir, parent_dir
def find_dotenv(
filename: str = '.env',
raise_error_if_not_found: bool = False,
usecwd: bool = False,
) -> str:
"""
Search in increasingly higher folders for the given file
Returns path to the file if found, or an empty string otherwise
"""
def _is_interactive():
""" Decide whether this is running in a REPL or IPython notebook """
try:
main = __import__('__main__', None, None, fromlist=['__file__'])
except ModuleNotFoundError:
return False
return not hasattr(main, '__file__')
if usecwd or _is_interactive() or getattr(sys, 'frozen', False):
# Should work without __file__, e.g. in REPL or IPython notebook.
path = os.getcwd()
else:
# will work for .py files
frame = sys._getframe()
current_file = __file__
while frame.f_code.co_filename == current_file or not os.path.exists(
frame.f_code.co_filename
):
assert frame.f_back is not None
frame = frame.f_back
frame_filename = frame.f_code.co_filename
path = os.path.dirname(os.path.abspath(frame_filename))
for dirname in _walk_to_root(path):
check_path = os.path.join(dirname, filename)
if os.path.isfile(check_path):
return check_path
if raise_error_if_not_found:
raise IOError('File not found')
return ''
def load_dotenv(
dotenv_path: Optional[StrPath] = None,
stream: Optional[IO[str]] = None,
verbose: bool = False,
override: bool = False,
interpolate: bool = True,
encoding: Optional[str] = "utf-8",
) -> bool:
"""Parse a .env file and then load all the variables found as environment variables.
Parameters:
dotenv_path: Absolute or relative path to .env file.
stream: Text stream (such as `io.StringIO`) with .env content, used if
`dotenv_path` is `None`.
verbose: Whether to output a warning the .env file is missing.
override: Whether to override the system environment variables with the variables
from the `.env` file.
encoding: Encoding to be used to read the file.
Returns:
Bool: True if at least one environment variable is set else False
If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the
.env file.
"""
if dotenv_path is None and stream is None:
dotenv_path = find_dotenv()
dotenv = DotEnv(
dotenv_path=dotenv_path,
stream=stream,
verbose=verbose,
interpolate=interpolate,
override=override,
encoding=encoding,
)
return dotenv.set_as_environment_variables()
def dotenv_values(
dotenv_path: Optional[StrPath] = None,
stream: Optional[IO[str]] = None,
verbose: bool = False,
interpolate: bool = True,
encoding: Optional[str] = "utf-8",
) -> Dict[str, Optional[str]]:
"""
Parse a .env file and return its content as a dict.
The returned dict will have `None` values for keys without values in the .env file.
For example, `foo=bar` results in `{"foo": "bar"}` whereas `foo` alone results in
`{"foo": None}`
Parameters:
dotenv_path: Absolute or relative path to the .env file.
stream: `StringIO` object with .env content, used if `dotenv_path` is `None`.
verbose: Whether to output a warning if the .env file is missing.
encoding: Encoding to be used to read the file.
If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the
.env file.
"""
if dotenv_path is None and stream is None:
dotenv_path = find_dotenv()
return DotEnv(
dotenv_path=dotenv_path,
stream=stream,
verbose=verbose,
interpolate=interpolate,
override=True,
encoding=encoding,
).dict()
+175
View File
@@ -0,0 +1,175 @@
import codecs
import re
from typing import (IO, Iterator, Match, NamedTuple, Optional, # noqa:F401
Pattern, Sequence, Tuple)
def make_regex(string: str, extra_flags: int = 0) -> Pattern[str]:
return re.compile(string, re.UNICODE | extra_flags)
_newline = make_regex(r"(\r\n|\n|\r)")
_multiline_whitespace = make_regex(r"\s*", extra_flags=re.MULTILINE)
_whitespace = make_regex(r"[^\S\r\n]*")
_export = make_regex(r"(?:export[^\S\r\n]+)?")
_single_quoted_key = make_regex(r"'([^']+)'")
_unquoted_key = make_regex(r"([^=\#\s]+)")
_equal_sign = make_regex(r"(=[^\S\r\n]*)")
_single_quoted_value = make_regex(r"'((?:\\'|[^'])*)'")
_double_quoted_value = make_regex(r'"((?:\\"|[^"])*)"')
_unquoted_value = make_regex(r"([^\r\n]*)")
_comment = make_regex(r"(?:[^\S\r\n]*#[^\r\n]*)?")
_end_of_line = make_regex(r"[^\S\r\n]*(?:\r\n|\n|\r|$)")
_rest_of_line = make_regex(r"[^\r\n]*(?:\r|\n|\r\n)?")
_double_quote_escapes = make_regex(r"\\[\\'\"abfnrtv]")
_single_quote_escapes = make_regex(r"\\[\\']")
class Original(NamedTuple):
string: str
line: int
class Binding(NamedTuple):
key: Optional[str]
value: Optional[str]
original: Original
error: bool
class Position:
def __init__(self, chars: int, line: int) -> None:
self.chars = chars
self.line = line
@classmethod
def start(cls) -> "Position":
return cls(chars=0, line=1)
def set(self, other: "Position") -> None:
self.chars = other.chars
self.line = other.line
def advance(self, string: str) -> None:
self.chars += len(string)
self.line += len(re.findall(_newline, string))
class Error(Exception):
pass
class Reader:
def __init__(self, stream: IO[str]) -> None:
self.string = stream.read()
self.position = Position.start()
self.mark = Position.start()
def has_next(self) -> bool:
return self.position.chars < len(self.string)
def set_mark(self) -> None:
self.mark.set(self.position)
def get_marked(self) -> Original:
return Original(
string=self.string[self.mark.chars:self.position.chars],
line=self.mark.line,
)
def peek(self, count: int) -> str:
return self.string[self.position.chars:self.position.chars + count]
def read(self, count: int) -> str:
result = self.string[self.position.chars:self.position.chars + count]
if len(result) < count:
raise Error("read: End of string")
self.position.advance(result)
return result
def read_regex(self, regex: Pattern[str]) -> Sequence[str]:
match = regex.match(self.string, self.position.chars)
if match is None:
raise Error("read_regex: Pattern not found")
self.position.advance(self.string[match.start():match.end()])
return match.groups()
def decode_escapes(regex: Pattern[str], string: str) -> str:
def decode_match(match: Match[str]) -> str:
return codecs.decode(match.group(0), 'unicode-escape') # type: ignore
return regex.sub(decode_match, string)
def parse_key(reader: Reader) -> Optional[str]:
char = reader.peek(1)
if char == "#":
return None
elif char == "'":
(key,) = reader.read_regex(_single_quoted_key)
else:
(key,) = reader.read_regex(_unquoted_key)
return key
def parse_unquoted_value(reader: Reader) -> str:
(part,) = reader.read_regex(_unquoted_value)
return re.sub(r"\s+#.*", "", part).rstrip()
def parse_value(reader: Reader) -> str:
char = reader.peek(1)
if char == u"'":
(value,) = reader.read_regex(_single_quoted_value)
return decode_escapes(_single_quote_escapes, value)
elif char == u'"':
(value,) = reader.read_regex(_double_quoted_value)
return decode_escapes(_double_quote_escapes, value)
elif char in (u"", u"\n", u"\r"):
return u""
else:
return parse_unquoted_value(reader)
def parse_binding(reader: Reader) -> Binding:
reader.set_mark()
try:
reader.read_regex(_multiline_whitespace)
if not reader.has_next():
return Binding(
key=None,
value=None,
original=reader.get_marked(),
error=False,
)
reader.read_regex(_export)
key = parse_key(reader)
reader.read_regex(_whitespace)
if reader.peek(1) == "=":
reader.read_regex(_equal_sign)
value: Optional[str] = parse_value(reader)
else:
value = None
reader.read_regex(_comment)
reader.read_regex(_end_of_line)
return Binding(
key=key,
value=value,
original=reader.get_marked(),
error=False,
)
except Error:
reader.read_regex(_rest_of_line)
return Binding(
key=None,
value=None,
original=reader.get_marked(),
error=True,
)
def parse_stream(stream: IO[str]) -> Iterator[Binding]:
reader = Reader(stream)
while reader.has_next():
yield parse_binding(reader)
+1
View File
@@ -0,0 +1 @@
# Marker file for PEP 561
@@ -0,0 +1,86 @@
import re
from abc import ABCMeta, abstractmethod
from typing import Iterator, Mapping, Optional, Pattern
_posix_variable: Pattern[str] = re.compile(
r"""
\$\{
(?P<name>[^\}:]*)
(?::-
(?P<default>[^\}]*)
)?
\}
""",
re.VERBOSE,
)
class Atom(metaclass=ABCMeta):
def __ne__(self, other: object) -> bool:
result = self.__eq__(other)
if result is NotImplemented:
return NotImplemented
return not result
@abstractmethod
def resolve(self, env: Mapping[str, Optional[str]]) -> str: ...
class Literal(Atom):
def __init__(self, value: str) -> None:
self.value = value
def __repr__(self) -> str:
return f"Literal(value={self.value})"
def __eq__(self, other: object) -> bool:
if not isinstance(other, self.__class__):
return NotImplemented
return self.value == other.value
def __hash__(self) -> int:
return hash((self.__class__, self.value))
def resolve(self, env: Mapping[str, Optional[str]]) -> str:
return self.value
class Variable(Atom):
def __init__(self, name: str, default: Optional[str]) -> None:
self.name = name
self.default = default
def __repr__(self) -> str:
return f"Variable(name={self.name}, default={self.default})"
def __eq__(self, other: object) -> bool:
if not isinstance(other, self.__class__):
return NotImplemented
return (self.name, self.default) == (other.name, other.default)
def __hash__(self) -> int:
return hash((self.__class__, self.name, self.default))
def resolve(self, env: Mapping[str, Optional[str]]) -> str:
default = self.default if self.default is not None else ""
result = env.get(self.name, default)
return result if result is not None else ""
def parse_variables(value: str) -> Iterator[Atom]:
cursor = 0
for match in _posix_variable.finditer(value):
(start, end) = match.span()
name = match["name"]
default = match["default"]
if start > cursor:
yield Literal(value=value[cursor:start])
yield Variable(name=name, default=default)
cursor = end
length = len(value)
if cursor < length:
yield Literal(value=value[cursor:length])
+1
View File
@@ -0,0 +1 @@
__version__ = "1.0.1"
@@ -1,992 +0,0 @@
../../Scripts/pip.exe,sha256=wVTlSM1CoHzfPpDxEAOsp6Jjwv-I_iqzOCFudVcKfJI,107893
../../Scripts/pip3.10.exe,sha256=AZt5rsH4BlFFFrekn19LvZKeuvhlzaPjf3hwlvXq6RQ,107893
../../Scripts/pip3.exe,sha256=AZt5rsH4BlFFFrekn19LvZKeuvhlzaPjf3hwlvXq6RQ,107893
pip-22.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pip-22.2.1.dist-info/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
pip-22.2.1.dist-info/METADATA,sha256=shj9XW4KG9MEp43PNu0VqMaNr0dbIBnk0SALqyhNu6Q,4197
pip-22.2.1.dist-info/RECORD,,
pip-22.2.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip-22.2.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
pip-22.2.1.dist-info/entry_points.txt,sha256=_ZUyZpzz1RdotcszCitH_lQ6yiWAKmaOcIkCEmkrePU,124
pip-22.2.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pip/__init__.py,sha256=TnK0qWewypiwM5sIDNYfy404XnpGnbemXiEH9cyPTWg,357
pip/__main__.py,sha256=mXwWDftNLMKfwVqKFWGE_uuBZvGSIiUELhLkeysIuZc,1198
pip/__pip-runner__.py,sha256=9cY5wjw19ypL7f1StHYjB9Ud2WqQvEcynma3hOoeIRU,1085
pip/__pycache__/__init__.cpython-310.pyc,,
pip/__pycache__/__main__.cpython-310.pyc,,
pip/__pycache__/__pip-runner__.cpython-310.pyc,,
pip/_internal/__init__.py,sha256=nnFCuxrPMgALrIDxSoy-H6Zj4W4UY60D-uL1aJyq0pc,573
pip/_internal/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/__pycache__/build_env.cpython-310.pyc,,
pip/_internal/__pycache__/cache.cpython-310.pyc,,
pip/_internal/__pycache__/configuration.cpython-310.pyc,,
pip/_internal/__pycache__/exceptions.cpython-310.pyc,,
pip/_internal/__pycache__/main.cpython-310.pyc,,
pip/_internal/__pycache__/pyproject.cpython-310.pyc,,
pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc,,
pip/_internal/__pycache__/wheel_builder.cpython-310.pyc,,
pip/_internal/build_env.py,sha256=Io06wf8aNlP1FkDYCbbuVFPGWAMJNys7l_p7r9CmEKE,9535
pip/_internal/cache.py,sha256=-FXxS81WOM-amtx3w7N8s20PfFIlHPX8X27FfOBql-I,10623
pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132
pip/_internal/cli/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc,,
pip/_internal/cli/__pycache__/base_command.cpython-310.pyc,,
pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc,,
pip/_internal/cli/__pycache__/command_context.cpython-310.pyc,,
pip/_internal/cli/__pycache__/main.cpython-310.pyc,,
pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc,,
pip/_internal/cli/__pycache__/parser.cpython-310.pyc,,
pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc,,
pip/_internal/cli/__pycache__/req_command.cpython-310.pyc,,
pip/_internal/cli/__pycache__/spinners.cpython-310.pyc,,
pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc,,
pip/_internal/cli/autocompletion.py,sha256=wY2JPZY2Eji1vhR7bVo-yCBPJ9LCy6P80iOAhZD1Vi8,6676
pip/_internal/cli/base_command.py,sha256=EiHzq1RBubmgYkhsVgJLNc4Y18koPUS1TzMVJwpnYxc,8146
pip/_internal/cli/cmdoptions.py,sha256=LKKpinHThNt7wtHqxwkWJpgCUcyQeTX0GUCqyXImAbc,29985
pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774
pip/_internal/cli/main.py,sha256=ioJ8IVlb2K1qLOxR-tXkee9lURhYV89CDM71MKag7YY,2472
pip/_internal/cli/main_parser.py,sha256=Q9TnytfuC5Z2JSjBFWVGtEdYLFy7rukNIb04movHdAo,2614
pip/_internal/cli/parser.py,sha256=tWP-K1uSxnJyXu3WE0kkH3niAYRBeuUaxeydhzOdhL4,10817
pip/_internal/cli/progress_bars.py,sha256=So4mPoSjXkXiSHiTzzquH3VVyVD_njXlHJSExYPXAow,1968
pip/_internal/cli/req_command.py,sha256=ypTutLv4j_efxC2f6C6aCQufxre-zaJdi5m_tWlLeBk,18172
pip/_internal/cli/spinners.py,sha256=rs_NveD0wCoJ9GiJJmOjGC1UPVK8isOQpQsFVE899zQ,5098
pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116
pip/_internal/commands/__init__.py,sha256=5oRO9O3dM2vGuh0bFw4HOVletryrz5HHMmmPWwJrH9U,3882
pip/_internal/commands/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/commands/__pycache__/cache.cpython-310.pyc,,
pip/_internal/commands/__pycache__/check.cpython-310.pyc,,
pip/_internal/commands/__pycache__/completion.cpython-310.pyc,,
pip/_internal/commands/__pycache__/configuration.cpython-310.pyc,,
pip/_internal/commands/__pycache__/debug.cpython-310.pyc,,
pip/_internal/commands/__pycache__/download.cpython-310.pyc,,
pip/_internal/commands/__pycache__/freeze.cpython-310.pyc,,
pip/_internal/commands/__pycache__/hash.cpython-310.pyc,,
pip/_internal/commands/__pycache__/help.cpython-310.pyc,,
pip/_internal/commands/__pycache__/index.cpython-310.pyc,,
pip/_internal/commands/__pycache__/inspect.cpython-310.pyc,,
pip/_internal/commands/__pycache__/install.cpython-310.pyc,,
pip/_internal/commands/__pycache__/list.cpython-310.pyc,,
pip/_internal/commands/__pycache__/search.cpython-310.pyc,,
pip/_internal/commands/__pycache__/show.cpython-310.pyc,,
pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc,,
pip/_internal/commands/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/commands/cache.py,sha256=muaT0mbL-ZUpn6AaushVAipzTiMwE4nV2BLbJBwt_KQ,7582
pip/_internal/commands/check.py,sha256=0gjXR7j36xJT5cs2heYU_dfOfpnFfzX8OoPNNoKhqdM,1685
pip/_internal/commands/completion.py,sha256=H0TJvGrdsoleuIyQKzJbicLFppYx2OZA0BLNpQDeFjI,4129
pip/_internal/commands/configuration.py,sha256=ZJRO2YMzI5vPA2ADTWZrSsvGd4q880CylCUzEUJziZY,9500
pip/_internal/commands/debug.py,sha256=kVjn-O1ixLk0webD0w9vfFFq_GCTUTd2hmLOnYtDCig,6573
pip/_internal/commands/download.py,sha256=vLtEY3QqIAddjAOGvJJsbaHJg7Har5TPa4UuOOL6Gn8,5058
pip/_internal/commands/freeze.py,sha256=gCjoD6foBZPBAAYx5t8zZLkJhsF_ZRtnb3dPuD7beO8,2951
pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703
pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132
pip/_internal/commands/index.py,sha256=1VVXXj5MsI2qH-N7uniQQyVkg-KCn_RdjiyiUmkUS5U,4762
pip/_internal/commands/inspect.py,sha256=mRJ9aIkBQN0IJ7Um8pzaxAzVPIgL8KfWHx1fWKJgUAQ,3374
pip/_internal/commands/install.py,sha256=nyZCUv7Oi8rScPe4WENgQ8Vd5n3OHzBuj2tw6khg4Ss,30315
pip/_internal/commands/list.py,sha256=wF2g5i4j_JyoRckO9FAeB7KhcFAnLboy0dL-G9fn7Eo,12148
pip/_internal/commands/search.py,sha256=sbBZiARRc050QquOKcCvOr2K3XLsoYebLKZGRi__iUI,5697
pip/_internal/commands/show.py,sha256=CJI8q4SSY0X346K1hi4Th8Nbyhl4nxPTBJUuzOlTaYE,6129
pip/_internal/commands/uninstall.py,sha256=0JQhifYxecNrJAwoILFwjm9V1V3liXzNT-y4bgRXXPw,3680
pip/_internal/commands/wheel.py,sha256=dar33wNjUyTN6Cy8PVxV5TerJS1u7pZmKoqgoYiQh7g,6307
pip/_internal/configuration.py,sha256=uBKTus43pDIO6IzT2mLWQeROmHhtnoabhniKNjPYvD0,13529
pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/base.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/installed.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/distributions/base.py,sha256=jrF1Vi7eGyqFqMHrieh1PIOrGU7KeCxhYPZnbvtmvGY,1221
pip/_internal/distributions/installed.py,sha256=NI2OgsgH9iBq9l5vB-56vOg5YsybOy-AU4VE5CSCO2I,729
pip/_internal/distributions/sdist.py,sha256=SQBdkatXSigKGG_SaD0U0p1Jwdfrg26UCNcHgkXZfdA,6494
pip/_internal/distributions/wheel.py,sha256=m-J4XO-gvFerlYsFzzSXYDvrx8tLZlJFTCgDxctn8ig,1164
pip/_internal/exceptions.py,sha256=U-dV1ixkSz6NAU6Aw9dosKi2EzZ5D3BA7ilYZuTLKeU,20912
pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30
pip/_internal/index/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/index/__pycache__/collector.cpython-310.pyc,,
pip/_internal/index/__pycache__/package_finder.cpython-310.pyc,,
pip/_internal/index/__pycache__/sources.cpython-310.pyc,,
pip/_internal/index/collector.py,sha256=UCB2bYQIbIV4IIcTWK7cfy8iYpdOIcDiNLGFDcL6c-A,20301
pip/_internal/index/package_finder.py,sha256=kmcMu5_i-BP6v3NQGY0_am1ezxM2Gk4t00arZMmm4sc,37596
pip/_internal/index/sources.py,sha256=SVyPitv08-Qalh2_Bk5diAJ9GAA_d-a93koouQodAG0,6557
pip/_internal/locations/__init__.py,sha256=pxbyuIew0-ZMHs-aGfUgrNlYXdHTqvEJj_mM3UWiH1U,17461
pip/_internal/locations/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc,,
pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc,,
pip/_internal/locations/__pycache__/base.cpython-310.pyc,,
pip/_internal/locations/_distutils.py,sha256=6aYLJT475os90AQJ0w6YtgJcYN86aa60Ld27q8rkRK8,6254
pip/_internal/locations/_sysconfig.py,sha256=nM-DiVHXWTxippdmN0MGVl5r7OIfIMy3vgDMlo8c_oo,7867
pip/_internal/locations/base.py,sha256=ufyDqPwZ4jLbScD44u8AwTVI-3ft8O78UGrroQI5f68,2573
pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340
pip/_internal/metadata/__init__.py,sha256=IeqRXbTeSreqClORmjA_4CMjkWA-trWdss7Oyimwosw,3535
pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/metadata/__pycache__/_json.cpython-310.pyc,,
pip/_internal/metadata/__pycache__/base.cpython-310.pyc,,
pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc,,
pip/_internal/metadata/_json.py,sha256=BTkWfFDrWFwuSodImjtbAh8wCL3isecbnjTb5E6UUDI,2595
pip/_internal/metadata/base.py,sha256=gOjhT0Mk4f6hCa8hzZIQKynIwpHzydnm6krwGTHTVhI,24596
pip/_internal/metadata/importlib/__init__.py,sha256=9ZVO8BoE7NEZPmoHp5Ap_NJo0HgNIezXXg-TFTtt3Z4,107
pip/_internal/metadata/importlib/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/metadata/importlib/__pycache__/_compat.cpython-310.pyc,,
pip/_internal/metadata/importlib/__pycache__/_dists.cpython-310.pyc,,
pip/_internal/metadata/importlib/__pycache__/_envs.cpython-310.pyc,,
pip/_internal/metadata/importlib/_compat.py,sha256=B_qZlMBcbf2VrjHw4Pz9gfk-c-W1Mzp2u_GAzoWWuLE,1493
pip/_internal/metadata/importlib/_dists.py,sha256=iEu6KvMdFIfq3ujQvsS0fvI9jDbp1qFC9SmOySfn_fY,7456
pip/_internal/metadata/importlib/_envs.py,sha256=-4O0PiYmxydf0e6upJ7X-_BR4DB46I_szlgx53hnJLs,7195
pip/_internal/metadata/pkg_resources.py,sha256=RfU--nYrkHAYJXfpoviyBHJA5b9Mw3Dc5HpeYwki1gE,9289
pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63
pip/_internal/models/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/models/__pycache__/candidate.cpython-310.pyc,,
pip/_internal/models/__pycache__/direct_url.cpython-310.pyc,,
pip/_internal/models/__pycache__/format_control.cpython-310.pyc,,
pip/_internal/models/__pycache__/index.cpython-310.pyc,,
pip/_internal/models/__pycache__/installation_report.cpython-310.pyc,,
pip/_internal/models/__pycache__/link.cpython-310.pyc,,
pip/_internal/models/__pycache__/scheme.cpython-310.pyc,,
pip/_internal/models/__pycache__/search_scope.cpython-310.pyc,,
pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc,,
pip/_internal/models/__pycache__/target_python.cpython-310.pyc,,
pip/_internal/models/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/models/candidate.py,sha256=6pcABsaR7CfIHlbJbr2_kMkVJFL_yrYjTx6SVWUnCPQ,990
pip/_internal/models/direct_url.py,sha256=HLO0sL2aYB6n45bwmd72TDN05sLHJlOQI8M01l2SH3I,5877
pip/_internal/models/format_control.py,sha256=DJpMYjxeYKKQdwNcML2_F0vtAh-qnKTYe-CpTxQe-4g,2520
pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
pip/_internal/models/installation_report.py,sha256=ad1arqtxrSFBvWnm6mRqmG12HLV3pZZcZcHrlTFIiqU,2617
pip/_internal/models/link.py,sha256=_5okBLOR7vshRltnD11SC3cyD0aSxOa0lMpKWIwQ5UY,10490
pip/_internal/models/scheme.py,sha256=3EFQp_ICu_shH1-TBqhl0QAusKCPDFOlgHFeN4XowWs,738
pip/_internal/models/search_scope.py,sha256=LwloG0PJAmtI1hFXIypsD95kWE9xfR5hf_a2v1Vw7sk,4520
pip/_internal/models/selection_prefs.py,sha256=KZdi66gsR-_RUXUr9uejssk3rmTHrQVJWeNA2sV-VSY,1907
pip/_internal/models/target_python.py,sha256=qKpZox7J8NAaPmDs5C_aniwfPDxzvpkrCKqfwndG87k,3858
pip/_internal/models/wheel.py,sha256=X_fakLR3OGF7HhrhwVXCUN-1wBwVCT2Lz0o3NguT_GQ,3575
pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50
pip/_internal/network/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/network/__pycache__/auth.cpython-310.pyc,,
pip/_internal/network/__pycache__/cache.cpython-310.pyc,,
pip/_internal/network/__pycache__/download.cpython-310.pyc,,
pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc,,
pip/_internal/network/__pycache__/session.cpython-310.pyc,,
pip/_internal/network/__pycache__/utils.cpython-310.pyc,,
pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc,,
pip/_internal/network/auth.py,sha256=a3C7Xaa8kTJjXkdi_wrUjqaySc8Z9Yz7U6QIbXfzMyc,12190
pip/_internal/network/cache.py,sha256=hgXftU-eau4MWxHSLquTMzepYq5BPC2zhCkhN3glBy8,2145
pip/_internal/network/download.py,sha256=HvDDq9bVqaN3jcS3DyVJHP7uTqFzbShdkf7NFSoHfkw,6096
pip/_internal/network/lazy_wheel.py,sha256=7YsbcpwOLyXbwCbR484ikhG9-C1FbUVABekVSBS0zHc,7637
pip/_internal/network/session.py,sha256=BpDOJ7_Xw5VkgPYWsePzcaqOfcyRZcB2AW7W0HGBST0,18443
pip/_internal/network/utils.py,sha256=6A5SrUJEEUHxbGtbscwU2NpCyz-3ztiDlGWHpRRhsJ8,4073
pip/_internal/network/xmlrpc.py,sha256=AzQgG4GgS152_cqmGr_Oz2MIXsCal-xfsis7fA7nmU0,1791
pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/operations/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/operations/__pycache__/check.cpython-310.pyc,,
pip/_internal/operations/__pycache__/freeze.cpython-310.pyc,,
pip/_internal/operations/__pycache__/prepare.cpython-310.pyc,,
pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/build_tracker.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc,,
pip/_internal/operations/build/build_tracker.py,sha256=vf81EwomN3xe9G8qRJED0VGqNikmRQRQoobNsxi5Xrs,4133
pip/_internal/operations/build/metadata.py,sha256=ES_uRmAvhrNm_nDTpZxshBfUsvnXtkj-g_4rZrH9Rww,1404
pip/_internal/operations/build/metadata_editable.py,sha256=_Rai0VZjxoeJUkjkuICrq45LtjwFoDOveosMYH43rKc,1456
pip/_internal/operations/build/metadata_legacy.py,sha256=o-eU21As175hDC7dluM1fJJ_FqokTIShyWpjKaIpHZw,2198
pip/_internal/operations/build/wheel.py,sha256=AO9XnTGhTgHtZmU8Dkbfo1OGr41rBuSDjIgAa4zUKgE,1063
pip/_internal/operations/build/wheel_editable.py,sha256=TVETY-L_M_dSEKBhTIcQOP75zKVXw8tuq1U354Mm30A,1405
pip/_internal/operations/build/wheel_legacy.py,sha256=C9j6rukgQI1n_JeQLoZGuDdfUwzCXShyIdPTp6edbMQ,3064
pip/_internal/operations/check.py,sha256=ca4O9CkPt9Em9sLCf3H0iVt1GIcW7M8C0U5XooaBuT4,5109
pip/_internal/operations/freeze.py,sha256=mwTZ2uML8aQgo3k8MR79a7SZmmmvdAJqdyaknKbavmg,9784
pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51
pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc,,
pip/_internal/operations/install/__pycache__/legacy.cpython-310.pyc,,
pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/operations/install/editable_legacy.py,sha256=ee4kfJHNuzTdKItbfAsNOSEwq_vD7DRPGkBdK48yBhU,1354
pip/_internal/operations/install/legacy.py,sha256=cHdcHebyzf8w7OaOLwcsTNSMSSV8WBoAPFLay_9CjE8,4105
pip/_internal/operations/install/wheel.py,sha256=ZbmrarCh74tariXY8rgI56jbZ1BJ2Z6u5fZt4nt3Gmw,27379
pip/_internal/operations/prepare.py,sha256=kvL-s1ZUs53g1JIzmJ62j8FwCO_fKWXN45pAtVuz0xE,22962
pip/_internal/pyproject.py,sha256=ob0Gb0l12YLZNxjdpZGRfWHgjqhZTnSVv96RuJyNOfs,7074
pip/_internal/req/__init__.py,sha256=rUQ9d_Sh3E5kNYqX9pkN0D06YL-LrtcbJQ-LiIonq08,2807
pip/_internal/req/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/req/__pycache__/constructors.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_file.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_install.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_set.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc,,
pip/_internal/req/constructors.py,sha256=ypjtq1mOQ3d2mFkFPMf_6Mr8SLKeHQk3tUKHA1ddG0U,16611
pip/_internal/req/req_file.py,sha256=Qgqx7qLfDO3ai72oO2U1u928_6Idajun5VFRWPZg3XM,17502
pip/_internal/req/req_install.py,sha256=bOtpOZnDgmEst_QuWZRXViaPW1JJ1iAvO6vVFgFf0PI,33506
pip/_internal/req/req_set.py,sha256=j3esG0s6SzoVReX9rWn4rpYNtyET_fwxbwJPRimvRxo,2858
pip/_internal/req/req_uninstall.py,sha256=ZFQfgSNz6H1BMsgl87nQNr2iaQCcbFcmXpW8rKVQcic,24045
pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/resolution/__pycache__/base.cpython-310.pyc,,
pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583
pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc,,
pip/_internal/resolution/legacy/resolver.py,sha256=9em8D5TcSsEN4xZM1WreaRShOnyM4LlvhMSHpUPsocE,24129
pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/base.py,sha256=u1O4fkvCO4mhmu5i32xrDv9AX5NgUci_eYVyBDQhTIM,5220
pip/_internal/resolution/resolvelib/candidates.py,sha256=6kQZeMzwibnL4lO6bW0hUQQjNEvXfADdFphRRkRvOtc,18963
pip/_internal/resolution/resolvelib/factory.py,sha256=OnjkLIgyk5Tol7uOOqapA1D4qiRHWmPU18DF1yN5N8o,27878
pip/_internal/resolution/resolvelib/found_candidates.py,sha256=hvL3Hoa9VaYo-qEOZkBi2Iqw251UDxPz-uMHVaWmLpE,5705
pip/_internal/resolution/resolvelib/provider.py,sha256=Vd4jW_NnyifB-HMkPYtZIO70M3_RM0MbL5YV6XyBM-w,9914
pip/_internal/resolution/resolvelib/reporter.py,sha256=3ZVVYrs5PqvLFJkGLcuXoMK5mTInFzl31xjUpDBpZZk,2526
pip/_internal/resolution/resolvelib/requirements.py,sha256=B1ndvKPSuyyyTEXt9sKhbwminViSWnBrJa7qO2ln4Z0,5455
pip/_internal/resolution/resolvelib/resolver.py,sha256=nYZ9bTFXj5c1ILKnkSgU7tUCTYyo5V5J-J0sKoA7Wzg,11533
pip/_internal/self_outdated_check.py,sha256=R3MmjCyUt_lkUNMc6p3xVSx7vX28XiDh3VDs5OrYn6Q,8020
pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/utils/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/utils/__pycache__/_log.cpython-310.pyc,,
pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc,,
pip/_internal/utils/__pycache__/compat.cpython-310.pyc,,
pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc,,
pip/_internal/utils/__pycache__/datetime.cpython-310.pyc,,
pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc,,
pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc,,
pip/_internal/utils/__pycache__/distutils_args.cpython-310.pyc,,
pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc,,
pip/_internal/utils/__pycache__/encoding.cpython-310.pyc,,
pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc,,
pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc,,
pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc,,
pip/_internal/utils/__pycache__/glibc.cpython-310.pyc,,
pip/_internal/utils/__pycache__/hashes.cpython-310.pyc,,
pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pyc,,
pip/_internal/utils/__pycache__/logging.cpython-310.pyc,,
pip/_internal/utils/__pycache__/misc.cpython-310.pyc,,
pip/_internal/utils/__pycache__/models.cpython-310.pyc,,
pip/_internal/utils/__pycache__/packaging.cpython-310.pyc,,
pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc,,
pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc,,
pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc,,
pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc,,
pip/_internal/utils/__pycache__/urls.cpython-310.pyc,,
pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc,,
pip/_internal/utils/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665
pip/_internal/utils/compat.py,sha256=ACyBfLgj3_XG-iA5omEDrXqDM0cQKzi8h8HRBInzG6Q,1884
pip/_internal/utils/compatibility_tags.py,sha256=ydin8QG8BHqYRsPY4OL6cmb44CbqXl1T0xxS97VhHkk,5377
pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242
pip/_internal/utils/deprecation.py,sha256=Ozzqnnl9kI0oQW6e2Pm3c-v0IZPy6gGERviDG45TmbY,3638
pip/_internal/utils/direct_url_helpers.py,sha256=6F1tc2rcKaCZmgfVwsE6ObIe_Pux23mUVYA-2D9wCFc,3206
pip/_internal/utils/distutils_args.py,sha256=bYUt4wfFJRaeGO4VHia6FNaA8HlYXMcKuEq1zYijY5g,1115
pip/_internal/utils/egg_link.py,sha256=5MVlpz5LirT4iLQq86OYzjXaYF0D4Qk1dprEI7ThST4,2203
pip/_internal/utils/encoding.py,sha256=qqsXDtiwMIjXMEiIVSaOjwH5YmirCaK-dIzb6-XJsL0,1169
pip/_internal/utils/entrypoints.py,sha256=GgeG2FUbbYhQ0sYgG2AtM-a4d1P8MJYdmEl5IhQ-WeM,2900
pip/_internal/utils/filesystem.py,sha256=RhMIXUaNVMGjc3rhsDahWQ4MavvEQDdqXqgq-F6fpw8,5122
pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716
pip/_internal/utils/glibc.py,sha256=tDfwVYnJCOC0BNVpItpy8CGLP9BjkxFHdl0mTS0J7fc,3110
pip/_internal/utils/hashes.py,sha256=EPVx_I0UI8Gvu_skgLwpJA90pHZ5Ev1qNaZagYOub7I,4811
pip/_internal/utils/inject_securetransport.py,sha256=o-QRVMGiENrTJxw3fAhA7uxpdEdw6M41TjHYtSVRrcg,795
pip/_internal/utils/logging.py,sha256=U2q0i1n8hPS2gQh8qcocAg5dovGAa_bR24akmXMzrk4,11632
pip/_internal/utils/misc.py,sha256=49Rs2NgrD4JGTKFt0farCm7FIAi-rjyoxgioArhCW_0,21617
pip/_internal/utils/models.py,sha256=5GoYU586SrxURMvDn_jBMJInitviJg4O5-iOU-6I0WY,1193
pip/_internal/utils/packaging.py,sha256=5Wm6_x7lKrlqVjPI5MBN_RurcRHwVYoQ7Ksrs84de7s,2108
pip/_internal/utils/setuptools_build.py,sha256=vNH9hQB9wT6d-h1hVQhBKw91jNeT42meHpVeii-urOI,5652
pip/_internal/utils/subprocess.py,sha256=MYySbvY7qBevRxq_RFfOsDqG4vMqrB4vDoL_eyPE6Bo,9197
pip/_internal/utils/temp_dir.py,sha256=aCX489gRa4Nu0dMKRFyGhV6maJr60uEynu5uCbKR4Qg,7702
pip/_internal/utils/unpacking.py,sha256=SBb2iV1crb89MDRTEKY86R4A_UOWApTQn9VQVcMDOlE,8821
pip/_internal/utils/urls.py,sha256=AhaesUGl-9it6uvG6fsFPOr9ynFpGaTMk4t5XTX7Z_Q,1759
pip/_internal/utils/virtualenv.py,sha256=4_48qMzCwB_F5jIK5BC_ua7uiAMVifmQWU9NdaGUoVA,3459
pip/_internal/utils/wheel.py,sha256=lXOgZyTlOm5HmK8tw5iw0A3_5A6wRzsXHOaQkIvvloU,4549
pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/git.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc,,
pip/_internal/vcs/bazaar.py,sha256=IGb5ca1xSZfgegRD2_JeyoZPrQQHs7lEYEIgpVsKpoU,3047
pip/_internal/vcs/git.py,sha256=mjhwudCx9WlLNkxZ6_kOKmueF0rLoU2i1xeASKF6yiQ,18116
pip/_internal/vcs/mercurial.py,sha256=Bzbd518Jsx-EJI0IhIobiQqiRsUv5TWYnrmRIFWE0Gw,5238
pip/_internal/vcs/subversion.py,sha256=TEMRdwECvMcXakZX0pTNUep79kmBYkWDkWFkrYmcmac,11718
pip/_internal/vcs/versioncontrol.py,sha256=KUOc-hN51em9jrqxKwUR3JnkgSE-xSOqMiiJcSaL6B8,22811
pip/_internal/wheel_builder.py,sha256=S-_i83q75xGqKjBenUl4uaTkLyXcZf7jFgChcCNi0xc,12712
pip/_vendor/__init__.py,sha256=fNxOSVD0auElsD8fN9tuq5psfgMQ-RFBtD4X5gjlRkg,4966
pip/_vendor/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/__pycache__/six.cpython-310.pyc,,
pip/_vendor/__pycache__/typing_extensions.cpython-310.pyc,,
pip/_vendor/cachecontrol/__init__.py,sha256=hrxlv3q7upsfyMw8k3gQ9vagBax1pYHSGGqYlZ0Zk0M,465
pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc,,
pip/_vendor/cachecontrol/_cmd.py,sha256=lxUXqfNTVx84zf6tcWbkLZHA6WVBRtJRpfeA9ZqhaAY,1379
pip/_vendor/cachecontrol/adapter.py,sha256=ew9OYEQHEOjvGl06ZsuX8W3DAvHWsQKHwWAxISyGug8,5033
pip/_vendor/cachecontrol/cache.py,sha256=Tty45fOjH40fColTGkqKQvQQmbYsMpk-nCyfLcv2vG4,1535
pip/_vendor/cachecontrol/caches/__init__.py,sha256=h-1cUmOz6mhLsjTjOrJ8iPejpGdLCyG4lzTftfGZvLg,242
pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc,,
pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc,,
pip/_vendor/cachecontrol/caches/file_cache.py,sha256=GpexcE29LoY4MaZwPUTcUBZaDdcsjqyLxZFznk8Hbr4,5271
pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=mp-QWonP40I3xJGK3XVO-Gs9a3UjzlqqEmp9iLJH9F4,1033
pip/_vendor/cachecontrol/compat.py,sha256=LNx7vqBndYdHU8YuJt53ab_8rzMGTXVrvMb7CZJkxG0,778
pip/_vendor/cachecontrol/controller.py,sha256=bAYrt7x_VH4toNpI066LQxbHpYGpY1MxxmZAhspplvw,16416
pip/_vendor/cachecontrol/filewrapper.py,sha256=X4BAQOO26GNOR7nH_fhTzAfeuct2rBQcx_15MyFBpcs,3946
pip/_vendor/cachecontrol/heuristics.py,sha256=8kAyuZLSCyEIgQr6vbUwfhpqg9ows4mM0IV6DWazevI,4154
pip/_vendor/cachecontrol/serialize.py,sha256=_U1NU_C-SDgFzkbAxAsPDgMTHeTWZZaHCQnZN_jh0U8,7105
pip/_vendor/cachecontrol/wrapper.py,sha256=X3-KMZ20Ho3VtqyVaXclpeQpFzokR5NE8tZSfvKVaB8,774
pip/_vendor/certifi/__init__.py,sha256=SuZ3iYmzdRyUv-PiaZkquUgXtWZ16ICUKgymlEBspx0,94
pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/certifi/__pycache__/core.cpython-310.pyc,,
pip/_vendor/certifi/cacert.pem,sha256=pZ_eiDoO-ddKudrQCWieABc9KFlbV0FsmLLugygMbkw,285222
pip/_vendor/certifi/core.py,sha256=g6EYcIFUAhYv5CB9B94iKRgMfGj8f82MF0CRdTDovxM,3052
pip/_vendor/chardet/__init__.py,sha256=9-r0i294avRciob2HKVcKf6GJmXPHpgMqIijVrqHBDU,3705
pip/_vendor/chardet/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/enums.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/escprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/escsm.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/johabfreq.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/johabprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/utf1632prober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pyc,,
pip/_vendor/chardet/__pycache__/version.cpython-310.pyc,,
pip/_vendor/chardet/big5freq.py,sha256=ltcfP-3PjlNHCoo5e4a7C4z-2DhBTXRfY6jbMbB7P30,31274
pip/_vendor/chardet/big5prober.py,sha256=neUXIlq35507yibstiznZWFzyNcMn6EXrqJaUJVPWKg,1741
pip/_vendor/chardet/chardistribution.py,sha256=M9NTKdM72KieFKy4TT5eml4PP0WaVcXuY5PpWSFD0FA,9608
pip/_vendor/chardet/charsetgroupprober.py,sha256=CaIBAmNitEsYuSgMvgAsMREN4cLxMj5OYwMhVo6MAxk,3817
pip/_vendor/chardet/charsetprober.py,sha256=Eo3w8sCmbvnVKOGNW1iy50KATVs8xV-gF7cQ0VG85dQ,4801
pip/_vendor/chardet/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pyc,,
pip/_vendor/chardet/cli/chardetect.py,sha256=1qMxT3wrp5vP6ugSf1-Zz3BWwlbCWJ0jzeCuhgX85vw,2406
pip/_vendor/chardet/codingstatemachine.py,sha256=BiGR9kgTYbS4gJI5qBmE52HMOBOR_roDvXf7aIehdEk,3559
pip/_vendor/chardet/cp949prober.py,sha256=kCQEaOCzMntqv7pAyXEobWTRgIUxYfoiUr0btXO1nI8,1838
pip/_vendor/chardet/enums.py,sha256=Rodw4p61Vg9U-oCo6eUuT7uDzKwIbCaA15HwbvCoCNk,1619
pip/_vendor/chardet/escprober.py,sha256=girD61r3NsQLnMQXsWWBU4hHuRJzTH3V7-VfTUr-nQY,3864
pip/_vendor/chardet/escsm.py,sha256=0Vs4iPPovberMoSxxnK5pI161Xf-mtKgOl14g5Xc7zg,12021
pip/_vendor/chardet/eucjpprober.py,sha256=pGgs4lINwCEDV2bxqIZ6hXpaj2j4l2oLsMx6kuOK_zQ,3676
pip/_vendor/chardet/euckrfreq.py,sha256=3mHuRvXfsq_QcQysDQFb8qSudvTiol71C6Ic2w57tKM,13566
pip/_vendor/chardet/euckrprober.py,sha256=qBuSS2zXWaoUmGdzz3owAnD1GNhuKR_8bYzDC3yxe6I,1731
pip/_vendor/chardet/euctwfreq.py,sha256=2alILE1Lh5eqiFJZjzRkMQXolNJRHY5oBQd-vmZYFFM,36913
pip/_vendor/chardet/euctwprober.py,sha256=SLnCoJC94jZL8PJio60Q8PZACJA1rVPtUdWMa1W8Pwk,1731
pip/_vendor/chardet/gb2312freq.py,sha256=49OrdXzD-HXqwavkqjo8Z7gvs58hONNzDhAyMENNkvY,20735
pip/_vendor/chardet/gb2312prober.py,sha256=NS_i52jZE0TnWGkKqFduvu9fzW0nMcS2XbYJ8qSX8hY,1737
pip/_vendor/chardet/hebrewprober.py,sha256=1l1hXF8-2IWDrPkf85UvAO1GVtMfY1r11kDgOqa-gU4,13919
pip/_vendor/chardet/jisfreq.py,sha256=mm8tfrwqhpOd3wzZKS4NJqkYBQVcDfTM2JiQ5aW932E,25796
pip/_vendor/chardet/johabfreq.py,sha256=dBpOYG34GRX6SL8k_LbS9rxZPMjLjoMlgZ03Pz5Hmqc,42498
pip/_vendor/chardet/johabprober.py,sha256=C18osd4vMPfy9facw-Y1Lor_9UrW0PeV-zxM2fu441c,1730
pip/_vendor/chardet/jpcntx.py,sha256=m1gDpPkRca4EDwym8XSL5YdoILFnFsDbNBYMQV7_-NE,26797
pip/_vendor/chardet/langbulgarianmodel.py,sha256=vmbvYFP8SZkSxoBvLkFqKiH1sjma5ihk3PTpdy71Rr4,104562
pip/_vendor/chardet/langgreekmodel.py,sha256=JfB7bupjjJH2w3X_mYnQr9cJA_7EuITC2cRW13fUjeI,98484
pip/_vendor/chardet/langhebrewmodel.py,sha256=3HXHaLQPNAGcXnJjkIJfozNZLTvTJmf4W5Awi6zRRKc,98196
pip/_vendor/chardet/langhungarianmodel.py,sha256=WxbeQIxkv8YtApiNqxQcvj-tMycsoI4Xy-fwkDHpP_Y,101363
pip/_vendor/chardet/langrussianmodel.py,sha256=s395bTZ87ESTrZCOdgXbEjZ9P1iGPwCl_8xSsac_DLY,128035
pip/_vendor/chardet/langthaimodel.py,sha256=7bJlQitRpTnVGABmbSznHnJwOHDy3InkTvtFUx13WQI,102774
pip/_vendor/chardet/langturkishmodel.py,sha256=XY0eGdTIy4eQ9Xg1LVPZacb-UBhHBR-cq0IpPVHowKc,95372
pip/_vendor/chardet/latin1prober.py,sha256=u_iGcQMUcZLXvj4B_WXx4caA0C5oaE2Qj1KTpz_RQ1I,5260
pip/_vendor/chardet/mbcharsetprober.py,sha256=iKKuB6o_FF80NynRLBDT0UtwOnpLqmL_OspRPMib7CM,3367
pip/_vendor/chardet/mbcsgroupprober.py,sha256=1D_kp9nv2_NQRddq9I2WDvB35OJh7Tfpo-OYTnL3B5o,2056
pip/_vendor/chardet/mbcssm.py,sha256=EfORNu1WXgnFvpFarU8uJHS8KFif63xmgrHOB4DdDdY,30068
pip/_vendor/chardet/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pyc,,
pip/_vendor/chardet/metadata/languages.py,sha256=HcaBygWtZq3gR8prIkJp_etvkhm2V4pUIToqjPZhgrc,13280
pip/_vendor/chardet/sbcharsetprober.py,sha256=VvtWiNRLbHDZ5xgnofsmP1u8VQIkkaAuw3Ir9m1zDzQ,6199
pip/_vendor/chardet/sbcsgroupprober.py,sha256=mekr4E3hgT4onmwi8oi1iEGW1CN-Z-BArG6kOtCunJw,4129
pip/_vendor/chardet/sjisprober.py,sha256=sLfWS25PVFr5cDGhEf6h_s-RJsyeSteA-4ynsTl_UvA,3749
pip/_vendor/chardet/universaldetector.py,sha256=BHeNWt1kn0yQgnR6xNtLAjiNmEQpSHYlKEvuZ9QyR1k,13288
pip/_vendor/chardet/utf1632prober.py,sha256=N42YJEOkVDB67c38t5aJhXMG1QvnyWWDMNY5ERzniU0,8289
pip/_vendor/chardet/utf8prober.py,sha256=mnLaSBV4gg-amt2WmxKFKWy4vVBedMNgjdbvgzBo0Dc,2709
pip/_vendor/chardet/version.py,sha256=u_QYi-DXU1s7fyC_Rwa0I0-UcxMVmH7Co6c7QGKbe3g,242
pip/_vendor/colorama/__init__.py,sha256=ihDoWQOkapwF7sqQ99AoDoEF3vGYm40OtmgW211cLZw,239
pip/_vendor/colorama/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/colorama/__pycache__/ansi.cpython-310.pyc,,
pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pyc,,
pip/_vendor/colorama/__pycache__/initialise.cpython-310.pyc,,
pip/_vendor/colorama/__pycache__/win32.cpython-310.pyc,,
pip/_vendor/colorama/__pycache__/winterm.cpython-310.pyc,,
pip/_vendor/colorama/ansi.py,sha256=Top4EeEuaQdBWdteKMEcGOTeKeF19Q-Wo_6_Cj5kOzQ,2522
pip/_vendor/colorama/ansitowin32.py,sha256=gGrO7MVtwc-j1Sq3jKfZpERT1JWmYSOsTVDiTnFbZU4,10830
pip/_vendor/colorama/initialise.py,sha256=PprovDNxMTrvoNHFcL2NZjpH2XzDc8BLxLxiErfUl4k,1915
pip/_vendor/colorama/win32.py,sha256=bJ8Il9jwaBN5BJ8bmN6FoYZ1QYuMKv2j8fGrXh7TJjw,5404
pip/_vendor/colorama/winterm.py,sha256=2y_2b7Zsv34feAsP67mLOVc-Bgq51mdYGo571VprlrM,6438
pip/_vendor/distlib/__init__.py,sha256=kshNHF2XFPxmBv57X7Jsj7c6VzF5r9naVwGePP-s5Wc,581
pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/database.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/index.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/util.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/version.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc,,
pip/_vendor/distlib/compat.py,sha256=tfoMrj6tujk7G4UC2owL6ArgDuCKabgBxuJRGZSmpko,41259
pip/_vendor/distlib/database.py,sha256=o_mw0fAr93NDAHHHfqG54Y1Hi9Rkfrp2BX15XWZYK50,51697
pip/_vendor/distlib/index.py,sha256=HFiDG7LMoaBs829WuotrfIwcErOOExUOR_AeBtw_TCU,20834
pip/_vendor/distlib/locators.py,sha256=wNzG-zERzS_XGls-nBPVVyLRHa2skUlkn0-5n0trMWA,51991
pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811
pip/_vendor/distlib/markers.py,sha256=TpHHHLgkzyT7YHbwj-2i6weRaq-Ivy2-MUnrDkjau-U,5058
pip/_vendor/distlib/metadata.py,sha256=g_DIiu8nBXRzA-mWPRpatHGbmFZqaFoss7z9TG7QSUU,39801
pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820
pip/_vendor/distlib/scripts.py,sha256=BmkTKmiTk4m2cj-iueliatwz3ut_9SsABBW51vnQnZU,18102
pip/_vendor/distlib/t32.exe,sha256=lD3IWCwZiYZ9onypJifi2R1sGS-S24t3mYupsEAOKyA,97792
pip/_vendor/distlib/t64-arm.exe,sha256=3hjLTLg7XBVHwDxgzZpkiHXXp4IJQMLvg_ZlGGpKZDI,182784
pip/_vendor/distlib/t64.exe,sha256=vvS31h4-SnumthypJJKAWBeBh7cxSJ8AwGmbqumM05k,107520
pip/_vendor/distlib/util.py,sha256=31dPXn3Rfat0xZLeVoFpuniyhe6vsbl9_QN-qd9Lhlk,66262
pip/_vendor/distlib/version.py,sha256=WG__LyAa2GwmA6qSoEJtvJE8REA1LZpbSizy8WvhJLk,23513
pip/_vendor/distlib/w32.exe,sha256=-a9nfgVZClK_mGnbQtXVLbn7xtPYw3xDKTddKnu2AJ8,91648
pip/_vendor/distlib/w64-arm.exe,sha256=LW-JyIIGblDOp8Psy8igJXDvcg_YpJIINvN0tRjfv18,168448
pip/_vendor/distlib/w64.exe,sha256=XvKqAoQzca86ERd2-KV5Vo1RSOBM28I2a35sPQONrYI,101888
pip/_vendor/distlib/wheel.py,sha256=Rgqs658VsJ3R2845qwnZD8XQryV2CzWw2mghwLvxxsI,43898
pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
pip/_vendor/distro/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/distro/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/distro/__pycache__/distro.cpython-310.pyc,,
pip/_vendor/distro/distro.py,sha256=UYQG_9H_iSOt422uasA92HlY7aXeTnWKdV-IhsSAdwQ,48841
pip/_vendor/idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849
pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/codec.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/core.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc,,
pip/_vendor/idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374
pip/_vendor/idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321
pip/_vendor/idna/core.py,sha256=RFIkY-HhFZaDoBEFjGwyGd_vWI04uOAQjnzueMWqwOU,12795
pip/_vendor/idna/idnadata.py,sha256=fzMzkCea2xieVxcrjngJ-2pLsKQNejPCZFlBajIuQdw,44025
pip/_vendor/idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881
pip/_vendor/idna/package_data.py,sha256=szxQhV0ZD0nKJ84Kuobw3l8q4_KeCyXjFRdpwIpKZmw,21
pip/_vendor/idna/uts46data.py,sha256=o-D7V-a0fOLZNd7tvxof6MYfUd0TBZzE2bLR5XO67xU,204400
pip/_vendor/msgpack/__init__.py,sha256=NryGaKLDk_Egd58ZxXpnuI7OWO27AXz7S6CBFRM3sAY,1132
pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc,,
pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc,,
pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
pip/_vendor/msgpack/ext.py,sha256=TuldJPkYu8Wo_Xh0tFGL2l06-gY88NSR8tOje9fo2Wg,6080
pip/_vendor/msgpack/fallback.py,sha256=OORDn86-fHBPlu-rPlMdM10KzkH6S_Rx9CHN1b7o4cg,34557
pip/_vendor/packaging/__about__.py,sha256=ugASIO2w1oUyH8_COqQ2X_s0rDhjbhQC3yJocD03h2c,661
pip/_vendor/packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497
pip/_vendor/packaging/__pycache__/__about__.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/version.cpython-310.pyc,,
pip/_vendor/packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488
pip/_vendor/packaging/_musllinux.py,sha256=_KGgY_qc7vhMGpoqss25n2hiLCNKRtvz9mCrS7gkqyc,4378
pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
pip/_vendor/packaging/markers.py,sha256=AJBOcY8Oq0kYc570KuuPTkvuqjAlhufaE2c9sCUbm64,8487
pip/_vendor/packaging/requirements.py,sha256=NtDlPBtojpn1IUC85iMjPNsUmufjpSlwnNA-Xb4m5NA,4676
pip/_vendor/packaging/specifiers.py,sha256=LRQ0kFsHrl5qfcFNEEJrIFYsnIHQUJXY9fIsakTrrqE,30110
pip/_vendor/packaging/tags.py,sha256=lmsnGNiJ8C4D_Pf9PbM0qgbZvD9kmB9lpZBQUZa3R_Y,15699
pip/_vendor/packaging/utils.py,sha256=dJjeat3BS-TYn1RrUFVwufUMasbtzLfYRoy_HXENeFQ,4200
pip/_vendor/packaging/version.py,sha256=_fLRNrFrxYcHVfyo8vk9j8s6JM8N_xsSxVFr6RJyco8,14665
pip/_vendor/pep517/__init__.py,sha256=Y1bATL2qbFNN6M_DQa4yyrwqjpIiL-j9T6kBmR0DS14,130
pip/_vendor/pep517/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/build.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/check.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/meta.cpython-310.pyc,,
pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pyc,,
pip/_vendor/pep517/build.py,sha256=2bar6EdjwIz2Dlfy94qdxn3oA9mVnnny40mfoT5f-qI,3457
pip/_vendor/pep517/check.py,sha256=bCORq1WrHjhpTONa-zpAqG0EB9rHNuhO1ORu6DsDuL8,6084
pip/_vendor/pep517/colorlog.py,sha256=Tk9AuYm_cLF3BKTBoSTJt9bRryn0aFojIQOwbfVUTxQ,4098
pip/_vendor/pep517/compat.py,sha256=NmLImE5oiDT3gbEhJ4w7xeoMFcpAPrGu_NltBytSJUY,1253
pip/_vendor/pep517/dirtools.py,sha256=2mkAkAL0mRz_elYFjRKuekTJVipH1zTn4tbf1EDev84,1129
pip/_vendor/pep517/envbuild.py,sha256=zFde--rmzjXMLXcm7SA_3hDtgk5VCTA8hjpk88RbF6E,6100
pip/_vendor/pep517/in_process/__init__.py,sha256=MyWoAi8JHdcBv7yXuWpUSVADbx6LSB9rZh7kTIgdA8Y,563
pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pyc,,
pip/_vendor/pep517/in_process/_in_process.py,sha256=D3waguyNSGcwosociD5USfcycYr2RCzCjYtxX5UHQmQ,11201
pip/_vendor/pep517/meta.py,sha256=8mnM5lDnT4zXQpBTliJbRGfesH7iioHwozbDxALPS9Y,2463
pip/_vendor/pep517/wrappers.py,sha256=impq7Cz_LL1iDF1iiOzYWB4MaEu6O6Gps7TJ5qsJz1Q,13429
pip/_vendor/pkg_resources/__init__.py,sha256=NnpQ3g6BCHzpMgOR_OLBmYtniY4oOzdKpwqghfq_6ug,108287
pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-310.pyc,,
pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562
pip/_vendor/platformdirs/__init__.py,sha256=x0aUmmovXXuRFVrVQBtwIiovX12B7rUkdV4F9UlLz0Y,12831
pip/_vendor/platformdirs/__main__.py,sha256=ZmsnTxEOxtTvwa-Y_Vfab_JN3X4XCVeN8X0yyy9-qnc,1176
pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc,,
pip/_vendor/platformdirs/android.py,sha256=GKizhyS7ESRiU67u8UnBJLm46goau9937EchXWbPBlk,4068
pip/_vendor/platformdirs/api.py,sha256=MXKHXOL3eh_-trSok-JUTjAR_zjmmKF3rjREVABjP8s,4910
pip/_vendor/platformdirs/macos.py,sha256=-3UXQewbT0yMhMdkzRXfXGAntmLIH7Qt4a9Hlf8I5_Y,2655
pip/_vendor/platformdirs/unix.py,sha256=b4aVYTz0qZ50HntwOXo8r6tp82jAa3qTjxw-WlnC2yc,6910
pip/_vendor/platformdirs/version.py,sha256=tsBKKPDX3LLh39yHXeTYauGRbRd-AmOJr9SwKldlFIU,78
pip/_vendor/platformdirs/windows.py,sha256=ISruopR5UGBePC0BxCxXevkZYfjJsIZc49YWU5iYfQ4,6439
pip/_vendor/pygments/__init__.py,sha256=M4yPkVb6x8OkEb4tHfVU8p6B3DBEsshB_8a2gZvr4FE,3002
pip/_vendor/pygments/__main__.py,sha256=p0_rz3JZmNZMNZBOqDojaEx1cr9wmA9FQZX_TYl74lQ,353
pip/_vendor/pygments/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/cmdline.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/console.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/filter.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/formatter.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/lexer.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/modeline.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/plugin.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/regexopt.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/scanner.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/sphinxext.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/style.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/token.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/unistring.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/util.cpython-310.pyc,,
pip/_vendor/pygments/cmdline.py,sha256=HYs14dbtMgL7t_BJ7B84NXlFjOzMYgW7Z0ZSxkTJun4,23408
pip/_vendor/pygments/console.py,sha256=hQfqCFuOlGk7DW2lPQYepsw-wkOH1iNt9ylNA1eRymM,1697
pip/_vendor/pygments/filter.py,sha256=NglMmMPTRRv-zuRSE_QbWid7JXd2J4AvwjCW2yWALXU,1938
pip/_vendor/pygments/filters/__init__.py,sha256=F8WwJguaJLs3bomEH8LyVATQfpULTpSpTd4PRPONR5A,40292
pip/_vendor/pygments/filters/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/formatter.py,sha256=6-TS2Y8pUMeWIUolWwr1O8ruC-U6HydWDwOdbAiJgJQ,2917
pip/_vendor/pygments/formatters/__init__.py,sha256=5LfCZThsbVVtZU5OyavkRPwC0MV7tB6pqcJ793PWi6E,5119
pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/groff.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/html.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/img.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/irc.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/latex.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/other.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/svg.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-310.pyc,,
pip/_vendor/pygments/formatters/_mapping.py,sha256=QLyYZ7Cv9W7YcM8seq0XqR3MXW3MzoFZSyHd7BDNU84,6517
pip/_vendor/pygments/formatters/bbcode.py,sha256=JrL4ITjN-KzPcuQpPMBf1pm33eW2sDUNr8WzSoAJsJA,3314
pip/_vendor/pygments/formatters/groff.py,sha256=xrOFoLbafSA9uHsSLRogy79_Zc4GWJ8tMK2hCdTJRsw,5086
pip/_vendor/pygments/formatters/html.py,sha256=QNt9prPgxmbKx2M-nfDwoR1bIg06-sNouQuWnE434Wc,35441
pip/_vendor/pygments/formatters/img.py,sha256=j3hHU1fhbBEIKEtWTV-vc-z-5c2nqoobOty3QqeQbpk,21819
pip/_vendor/pygments/formatters/irc.py,sha256=iwk5tDJOxbCV64SCmOFyvk__x6RD60ay0nUn7ko9n7U,5871
pip/_vendor/pygments/formatters/latex.py,sha256=thPbytJCIs2AUXsO3NZwqKtXJ-upOlcXP4CXsx94G4w,19351
pip/_vendor/pygments/formatters/other.py,sha256=PczqK1Rms43lz6iucOLPeBMxIncPKOGBt-195w1ynII,5073
pip/_vendor/pygments/formatters/pangomarkup.py,sha256=ZZzMsKJKXrsDniFeMTkIpe7aQ4VZYRHu0idWmSiUJ2U,2212
pip/_vendor/pygments/formatters/rtf.py,sha256=abrKlWjipBkQvhIICxtjYTUNv6WME0iJJObFvqVuudE,5014
pip/_vendor/pygments/formatters/svg.py,sha256=6MM9YyO8NhU42RTQfTWBiagWMnsf9iG5gwhqSriHORE,7335
pip/_vendor/pygments/formatters/terminal.py,sha256=NpEGvwkC6LgMLQTjVzGrJXji3XcET1sb5JCunSCzoRo,4674
pip/_vendor/pygments/formatters/terminal256.py,sha256=4v4OVizvsxtwWBpIy_Po30zeOzE5oJg_mOc1-rCjMDk,11753
pip/_vendor/pygments/lexer.py,sha256=ZPB_TGn_qzrXodRFwEdPzzJk6LZBo9BlfSy3lacc6zg,32005
pip/_vendor/pygments/lexers/__init__.py,sha256=Gku6kqn9IvgIdvV50gISPo0mmyyMNYRoUliEwhw6eNY,11491
pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-310.pyc,,
pip/_vendor/pygments/lexers/__pycache__/python.cpython-310.pyc,,
pip/_vendor/pygments/lexers/_mapping.py,sha256=sExOsmEbtg7hKwXgSz6M3L77cKPaOgskzxOCdw_GxVc,72083
pip/_vendor/pygments/lexers/python.py,sha256=QWj4ud4brZCj0-LXjR7IcO0kL6lqM2HzM_DzZZxMRjg,52792
pip/_vendor/pygments/modeline.py,sha256=gIbMSYrjSWPk0oATz7W9vMBYkUyTK2OcdVyKjioDRvA,986
pip/_vendor/pygments/plugin.py,sha256=tIRWetjR4dokpgbbFnsx7jjfN57T4-Z4errH1eVgGYw,1727
pip/_vendor/pygments/regexopt.py,sha256=c6xcXGpGgvCET_3VWawJJqAnOp0QttFpQEdOPNY2Py0,3072
pip/_vendor/pygments/scanner.py,sha256=F2T2G6cpkj-yZtzGQr-sOBw5w5-96UrJWveZN6va2aM,3092
pip/_vendor/pygments/sphinxext.py,sha256=F8L0211sPnXaiWutN0lkSUajWBwlgDMIEFFAbMWOvZY,4630
pip/_vendor/pygments/style.py,sha256=RRnussX1YiK9Z7HipIvKorImxu3-HnkdpPCO4u925T0,6257
pip/_vendor/pygments/styles/__init__.py,sha256=eVJlJqbmc-TYSQEEl-2yhbtnW6INfuvlayJOiXrt9ro,3252
pip/_vendor/pygments/styles/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/token.py,sha256=naybicpgOtSlh3vMGvbbx2T_6qEdGWYEH_RJ4gacIcc,6143
pip/_vendor/pygments/unistring.py,sha256=gP3gK-6C4oAFjjo9HvoahsqzuV4Qz0jl0E0OxfDerHI,63187
pip/_vendor/pygments/util.py,sha256=KgwpWWC3By5AiNwxGTI7oI9aXupH2TyZWukafBJe0Mg,9110
pip/_vendor/pyparsing/__init__.py,sha256=ZPdI7pPo4IYXcABw-51AcqOzsxVvDtqnQbyn_qYWZvo,9171
pip/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/common.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/core.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/results.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc,,
pip/_vendor/pyparsing/__pycache__/util.cpython-310.pyc,,
pip/_vendor/pyparsing/actions.py,sha256=wU9i32e0y1ymxKE3OUwSHO-SFIrt1h_wv6Ws0GQjpNU,6426
pip/_vendor/pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936
pip/_vendor/pyparsing/core.py,sha256=AzTm1KFT1FIhiw2zvXZJmrpQoAwB0wOmeDCiR6SYytw,213344
pip/_vendor/pyparsing/diagram/__init__.py,sha256=KW0PV_TvWKnL7jysz0pQbZ24nzWWu2ZfNaeyUIIywIg,23685
pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pyparsing/exceptions.py,sha256=3LbSafD32NYb1Tzt85GHNkhEAU1eZkTtNSk24cPMemo,9023
pip/_vendor/pyparsing/helpers.py,sha256=QpUOjW0-psvueMwWb9bQpU2noqKCv98_wnw1VSzSdVo,39129
pip/_vendor/pyparsing/results.py,sha256=HgNvWVXBdQP-Q6PtJfoCEeOJk2nwEvG-2KVKC5sGA30,25341
pip/_vendor/pyparsing/testing.py,sha256=7tu4Abp4uSeJV0N_yEPRmmNUhpd18ZQP3CrX41DM814,13402
pip/_vendor/pyparsing/unicode.py,sha256=fwuhMj30SQ165Cv7HJpu-rSxGbRm93kN9L4Ei7VGc1Y,10787
pip/_vendor/pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805
pip/_vendor/requests/__init__.py,sha256=3XN75ZS4slWy3TQsEGF7-Q6l2R146teU-s2_rXNhxhU,5178
pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/api.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/auth.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/certs.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/help.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/models.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/packages.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/structures.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/utils.cpython-310.pyc,,
pip/_vendor/requests/__version__.py,sha256=nJVa3ef2yRyeYMhy7yHnRyjjpnNTDykZsE4Sp9irBC4,440
pip/_vendor/requests/_internal_utils.py,sha256=aSPlF4uDhtfKxEayZJJ7KkAxtormeTfpwKSBSwtmAUw,1397
pip/_vendor/requests/adapters.py,sha256=GFEz5koZaMZD86v0SHXKVB5SE9MgslEjkCQzldkNwVM,21443
pip/_vendor/requests/api.py,sha256=dyvkDd5itC9z2g0wHl_YfD1yf6YwpGWLO7__8e21nks,6377
pip/_vendor/requests/auth.py,sha256=h-HLlVx9j8rKV5hfSAycP2ApOSglTz77R0tz7qCbbEE,10187
pip/_vendor/requests/certs.py,sha256=kHDlkK_beuHXeMPc5jta2wgl8gdKeUWt5f2nTDVrvt8,441
pip/_vendor/requests/compat.py,sha256=IhK9quyX0RRuWTNcg6d2JGSAOUbM6mym2p_2XjLTwf4,1286
pip/_vendor/requests/cookies.py,sha256=kD3kNEcCj-mxbtf5fJsSaT86eGoEYpD3X0CSgpzl7BM,18560
pip/_vendor/requests/exceptions.py,sha256=FA-_kVwBZ2jhXauRctN_ewHVK25b-fj0Azyz1THQ0Kk,3823
pip/_vendor/requests/help.py,sha256=FnAAklv8MGm_qb2UilDQgS6l0cUttiCFKUjx0zn2XNA,3879
pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
pip/_vendor/requests/models.py,sha256=GZRMMrGwDOLVvVfFHLUq0qTfIWDla3NcFHa1f5xs9Q8,35287
pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695
pip/_vendor/requests/sessions.py,sha256=KUqJcRRLovNefUs7ScOXSUVCcfSayTFWtbiJ7gOSlTI,30180
pip/_vendor/requests/status_codes.py,sha256=FvHmT5uH-_uimtRz5hH9VCbt7VV-Nei2J9upbej6j8g,4235
pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
pip/_vendor/requests/utils.py,sha256=0gzSOcx9Ya4liAbHnHuwt4jM78lzCZZoDFgkmsInNUg,33240
pip/_vendor/resolvelib/__init__.py,sha256=UL-B2BDI0_TRIqkfGwLHKLxY-LjBlomz7941wDqzB1I,537
pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc,,
pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc,,
pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156
pip/_vendor/resolvelib/providers.py,sha256=roVmFBItQJ0TkhNua65h8LdNny7rmeqVEXZu90QiP4o,5872
pip/_vendor/resolvelib/reporters.py,sha256=fW91NKf-lK8XN7i6Yd_rczL5QeOT3sc6AKhpaTEnP3E,1583
pip/_vendor/resolvelib/resolvers.py,sha256=2wYzVGBGerbmcIpH8cFmgSKgLSETz8jmwBMGjCBMHG4,17592
pip/_vendor/resolvelib/structs.py,sha256=IVIYof6sA_N4ZEiE1C1UhzTX495brCNnyCdgq6CYq28,4794
pip/_vendor/rich/__init__.py,sha256=zREyQ22R3zKg8gMdhiikczdVQYtZNeayHNrbBg5scm0,5944
pip/_vendor/rich/__main__.py,sha256=BmTmBWI93ytq75IEPi1uAAdeRYzFfDbgaAXjsX1ogig,8808
pip/_vendor/rich/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_cell_widths.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_emoji_codes.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_emoji_replace.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_export_format.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_extension.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_inspect.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_log_render.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_loop.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_palettes.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_pick.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_ratio.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_spinners.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_stack.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_timer.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_win32_console.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_windows.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_windows_renderer.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_wrap.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/abc.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/align.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/ansi.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/bar.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/box.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/cells.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/color.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/color_triplet.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/columns.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/console.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/constrain.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/containers.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/control.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/default_styles.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/diagnose.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/emoji.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/errors.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/file_proxy.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/filesize.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/highlighter.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/json.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/jupyter.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/layout.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/live.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/live_render.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/logging.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/markup.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/measure.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/padding.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/pager.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/palette.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/panel.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/pretty.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/progress.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/progress_bar.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/prompt.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/protocol.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/region.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/repr.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/rule.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/scope.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/screen.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/segment.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/spinner.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/status.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/style.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/styled.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/syntax.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/table.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/terminal_theme.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/text.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/theme.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/themes.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/traceback.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/tree.cpython-310.pyc,,
pip/_vendor/rich/_cell_widths.py,sha256=2n4EiJi3X9sqIq0O16kUZ_zy6UYMd3xFfChlKfnW1Hc,10096
pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
pip/_vendor/rich/_export_format.py,sha256=nHArqOljIlYn6NruhWsAsh-fHo7oJC3y9BDJyAa-QYQ,2114
pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
pip/_vendor/rich/_inspect.py,sha256=oZJGw31e64dwXSCmrDnvZbwVb1ZKhWfU8wI3VWohjJk,9695
pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
pip/_vendor/rich/_ratio.py,sha256=2lLSliL025Y-YMfdfGbutkQDevhcyDqc-DtUYW9mU70,5472
pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
pip/_vendor/rich/_win32_console.py,sha256=P0vxI2fcndym1UU1S37XAzQzQnkyY7YqAKmxm24_gug,22820
pip/_vendor/rich/_windows.py,sha256=dvNl9TmfPzNVxiKk5WDFihErZ5796g2UC9-KGGyfXmk,1926
pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
pip/_vendor/rich/_wrap.py,sha256=xfV_9t0Sg6rzimmrDru8fCVmUlalYAcHLDfrJZnbbwQ,1840
pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
pip/_vendor/rich/align.py,sha256=FV6_GS-8uhIyViMng3hkIWSFaTgMohK1Oqyjl8I8mGE,10368
pip/_vendor/rich/ansi.py,sha256=HtaPG7dvgL6_yo0sQmx5CM05DJ4_1goY5SWXXOYNaKs,6820
pip/_vendor/rich/bar.py,sha256=a7UD303BccRCrEhGjfMElpv5RFYIinaAhAuqYqhUvmw,3264
pip/_vendor/rich/box.py,sha256=1Iv1sUWqjtp5XwLwGH-AJ8HgyXZ7dRFUkO0z3M_bRl8,9864
pip/_vendor/rich/cells.py,sha256=zMjFI15wCpgjLR14lHdfFMVC6qMDi5OsKIB0PYZBBMk,4503
pip/_vendor/rich/color.py,sha256=kp87L8V4-3qayE6CUxtW_nP8Ujfew_-DAhNwYMXBMOY,17957
pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
pip/_vendor/rich/console.py,sha256=bTT9DNX03V4cQXefg22d-gLSs_e_ZY2zdCvLIlEyU2Q,95885
pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
pip/_vendor/rich/containers.py,sha256=aKgm5UDHn5Nmui6IJaKdsZhbHClh_X7D-_Wg8Ehrr7s,5497
pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630
pip/_vendor/rich/default_styles.py,sha256=WqVh-RPNEsx0Wxf3fhS_fCn-wVqgJ6Qfo-Zg7CoCsLE,7954
pip/_vendor/rich/diagnose.py,sha256=an6uouwhKPAlvQhYpNNpGq9EJysfMIOvvCbO3oSoR24,972
pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501
pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
pip/_vendor/rich/file_proxy.py,sha256=4gCbGRXg0rW35Plaf0UVvj3dfENHuzc_n8I_dBqxI7o,1616
pip/_vendor/rich/filesize.py,sha256=yShoVpARafJBreyZFaAhC4OhnJ6ydC1WXR-Ez4wU_YQ,2507
pip/_vendor/rich/highlighter.py,sha256=3WW6PACGlq0e3YDjfqiMBQ0dYZwu7pcoFYUgJy01nb0,9585
pip/_vendor/rich/json.py,sha256=RCm4lXBXrjvXHpqrWPH8wdGP0jEo4IohLmkddlhRY18,5051
pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
pip/_vendor/rich/layout.py,sha256=E3xJ4fomizUADwime3VA0lBXoMSPl9blEokIzVBjO0Q,14074
pip/_vendor/rich/live.py,sha256=emVaLUua-FKSYqZXmtJJjBIstO99CqMOuA6vMAKVkO0,14172
pip/_vendor/rich/live_render.py,sha256=zElm3PrfSIvjOce28zETHMIUf9pFYSUA5o0AflgUP64,3667
pip/_vendor/rich/logging.py,sha256=10j13lPr-QuYqEEBz_2aRJp8gNYvSN2wmCUlUqJcPLM,11471
pip/_vendor/rich/markup.py,sha256=xzF4uAafiEeEYDJYt_vUnJOGoTU8RrH-PH7WcWYXjCg,8198
pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
pip/_vendor/rich/padding.py,sha256=kTFGsdGe0os7tXLnHKpwTI90CXEvrceeZGCshmJy5zw,4970
pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
pip/_vendor/rich/panel.py,sha256=CzdojkDAjxAKgvDxis47nWzUh1V2NniOqkJJQajosG8,8744
pip/_vendor/rich/pretty.py,sha256=CalVLVW3mvTn1hvI9Pgi2v-y4S-5zUWBK-PH7SlVs-U,36576
pip/_vendor/rich/progress.py,sha256=zjQRwd3TmDnAvSjTPsNPHFjmqE9GOEX3bf0Lj56hIL8,59746
pip/_vendor/rich/progress_bar.py,sha256=zHHaFPEfIhW2fq6Fnl5vBY7AUpP1N0HVGElISUHsnqw,8161
pip/_vendor/rich/prompt.py,sha256=x0mW-pIPodJM4ry6grgmmLrl8VZp99kqcmdnBe70YYA,11303
pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
pip/_vendor/rich/repr.py,sha256=Je91CIrZN_av9L3FRCKCs5yoX2LvczrCNKqUbVsjUvQ,4449
pip/_vendor/rich/rule.py,sha256=V6AWI0wCb6DB0rvN967FRMlQrdlG7HoZdfEAHyeG8CM,4773
pip/_vendor/rich/scope.py,sha256=HX13XsJfqzQHpPfw4Jn9JmJjCsRj9uhHxXQEqjkwyLA,2842
pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
pip/_vendor/rich/segment.py,sha256=6XdX0MfL18tUCaUWDWncIqx0wpq3GiaqzhYP779JvRA,24224
pip/_vendor/rich/spinner.py,sha256=7b8MCleS4fa46HX0AzF98zfu6ZM6fAL0UgYzPOoakF4,4374
pip/_vendor/rich/status.py,sha256=gJsIXIZeSo3urOyxRUjs6VrhX5CZrA0NxIQ-dxhCnwo,4425
pip/_vendor/rich/style.py,sha256=4WnUEkHNMp9Tfmd8cmbxWGby7QeTk2LUTQzFSs46EQc,26240
pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
pip/_vendor/rich/syntax.py,sha256=_M08KbE11nNWNBPooFLKAA7lWkThPzlGUsuesxQYsuA,34697
pip/_vendor/rich/table.py,sha256=r_lahmj45cINCWLYaIjq9yEv3gve8E6bkYTP8NDqApE,39515
pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
pip/_vendor/rich/text.py,sha256=oajdGIeHcLcSdOwbC48_20ylDsHAS5fsPZD_Ih0clyA,44666
pip/_vendor/rich/theme.py,sha256=GKNtQhDBZKAzDaY0vQVQQFzbc0uWfFe6CJXA-syT7zQ,3627
pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
pip/_vendor/rich/traceback.py,sha256=MORQpXH7AvhAAThW8oIbtwffXb8M6XRkSkcJ52JuA3g,26060
pip/_vendor/rich/tree.py,sha256=BMbUYNjS9uodNPfvtY_odmU09GA5QzcMbQ5cJZhllQI,9169
pip/_vendor/six.py,sha256=TOOfQi7nFGfMrIvtdr6wX4wyHH8M7aknmuLfo2cBBrM,34549
pip/_vendor/tenacity/__init__.py,sha256=GLLsTFD4Bd5VDgTR6mU_FxyOsrxc48qONorVaRebeD4,18257
pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/after.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/before.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/nap.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/retry.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/stop.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pyc,,
pip/_vendor/tenacity/__pycache__/wait.cpython-310.pyc,,
pip/_vendor/tenacity/_asyncio.py,sha256=HEb0BVJEeBJE9P-m9XBxh1KcaF96BwoeqkJCL5sbVcQ,3314
pip/_vendor/tenacity/_utils.py,sha256=-y68scDcyoqvTJuJJ0GTfjdSCljEYlbCYvgk7nM4NdM,1944
pip/_vendor/tenacity/after.py,sha256=dlmyxxFy2uqpLXDr838DiEd7jgv2AGthsWHGYcGYsaI,1496
pip/_vendor/tenacity/before.py,sha256=7XtvRmO0dRWUp8SVn24OvIiGFj8-4OP5muQRUiWgLh0,1376
pip/_vendor/tenacity/before_sleep.py,sha256=ThyDvqKU5yle_IvYQz_b6Tp6UjUS0PhVp6zgqYl9U6Y,1908
pip/_vendor/tenacity/nap.py,sha256=fRWvnz1aIzbIq9Ap3gAkAZgDH6oo5zxMrU6ZOVByq0I,1383
pip/_vendor/tenacity/retry.py,sha256=62R71W59bQjuNyFKsDM7hE2aEkEPtwNBRA0tnsEvgSk,6645
pip/_vendor/tenacity/stop.py,sha256=sKHmHaoSaW6sKu3dTxUVKr1-stVkY7lw4Y9yjZU30zQ,2790
pip/_vendor/tenacity/tornadoweb.py,sha256=E8lWO2nwe6dJgoB-N2HhQprYLDLB_UdSgFnv-EN6wKE,2145
pip/_vendor/tenacity/wait.py,sha256=e_Saa6I2tsNLpCL1t9897wN2fGb0XQMQlE4bU2t9V2w,6691
pip/_vendor/tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396
pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc,,
pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc,,
pip/_vendor/tomli/__pycache__/_types.cpython-310.pyc,,
pip/_vendor/tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633
pip/_vendor/tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943
pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
pip/_vendor/typing_extensions.py,sha256=U_PyumPFBkMiR_Iq78QWZXdPprTywptECB2WRIQjDv0,75420
pip/_vendor/urllib3/__init__.py,sha256=j3yzHIbmW7CS-IKQJ9-PPQf_YKO8EOAey_rMW0UR7us,2763
pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc,,
pip/_vendor/urllib3/_collections.py,sha256=Rp1mVyBgc_UlAcp6M3at1skJBXR5J43NawRTvW2g_XY,10811
pip/_vendor/urllib3/_version.py,sha256=kDAZ-bEcWgqZsVJELrYbVo4buZP5eBBOGl_X7VA0Ic4,64
pip/_vendor/urllib3/connection.py,sha256=8976wL6sGeVMW0JnXvx5mD00yXu87uQjxtB9_VL8dx8,20070
pip/_vendor/urllib3/connectionpool.py,sha256=vEzk1iJEw1qR2vHBo7m3Y98iDfna6rKkUz3AyK5lJKQ,39093
pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
pip/_vendor/urllib3/contrib/appengine.py,sha256=lfzpHFmJiO82shClLEm3QB62SYgHWnjpZOH_2JhU5Tc,11034
pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=ej9gGvfAb2Gt00lafFp45SIoRz-QwrQ4WChm6gQmAlM,4538
pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=oR_4W0U0gaDYBN8Q5qz_VZ8xrYZsoXve52RwIKdYGbc,16899
pip/_vendor/urllib3/contrib/securetransport.py,sha256=yhZdmVjY6PI6EeFbp7qYOp6-vp1Rkv2NMuOGaEj7pmc,34448
pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
pip/_vendor/urllib3/poolmanager.py,sha256=0KOOJECoeLYVjUHvv-0h4Oq3FFQQ2yb-Fnjkbj8gJO0,19786
pip/_vendor/urllib3/request.py,sha256=ZFSIqX0C6WizixecChZ3_okyu7BEv0lZu1VT0s6h4SM,5985
pip/_vendor/urllib3/response.py,sha256=36JUM28H4dHsuCQgIPeN91LNcK8r1wBUJGFLk3ALfJc,28156
pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc,,
pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997
pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
pip/_vendor/urllib3/util/retry.py,sha256=iESg2PvViNdXBRY4MpL4h0kqwOOkHkxmLn1kkhFHPU8,22001
pip/_vendor/urllib3/util/ssl_.py,sha256=X4-AqW91aYPhPx6-xbf66yHFQKbqqfC_5Zt4WkLX1Hc,17177
pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
pip/_vendor/urllib3/util/timeout.py,sha256=QSbBUNOB9yh6AnDn61SrLQ0hg5oz0I9-uXEG91AJuIg,10003
pip/_vendor/urllib3/util/url.py,sha256=49HwObaTUUjqVe4qvSUvIjZyf3ghgNA6-OLm3kmkFKM,14287
pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
pip/_vendor/vendor.txt,sha256=8XILGklF_LcEc20OonK8_bpFH7tG7wLotFxI0k3FMU0,469
pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579
pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/webencodings/__pycache__/labels.cpython-310.pyc,,
pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pyc,,
pip/_vendor/webencodings/__pycache__/tests.cpython-310.pyc,,
pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pyc,,
pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979
pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305
pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563
pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307
pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
@@ -0,0 +1,806 @@
@Switch01
A_Rog
Aakanksha Agrawal
Abhinav Sagar
ABHYUDAY PRATAP SINGH
abs51295
AceGentile
Adam Chainz
Adam Tse
Adam Wentz
admin
Adolfo Ochagavía
Adrien Morison
Agus
ahayrapetyan
Ahilya
AinsworthK
Akash Srivastava
Alan Yee
Albert Tugushev
Albert-Guan
albertg
Alberto Sottile
Aleks Bunin
Ales Erjavec
Alethea Flowers
Alex Gaynor
Alex Grönholm
Alex Hedges
Alex Loosley
Alex Morega
Alex Stachowiak
Alexander Shtyrov
Alexandre Conrad
Alexey Popravka
Aleš Erjavec
Alli
Ami Fischman
Ananya Maiti
Anatoly Techtonik
Anders Kaseorg
Andre Aguiar
Andreas Lutro
Andrei Geacar
Andrew Gaul
Andrew Shymanel
Andrey Bienkowski
Andrey Bulgakov
Andrés Delfino
Andy Freeland
Andy Kluger
Ani Hayrapetyan
Aniruddha Basak
Anish Tambe
Anrs Hu
Anthony Sottile
Antoine Musso
Anton Ovchinnikov
Anton Patrushev
Anton Zelenov
Antonio Alvarado Hernandez
Antony Lee
Antti Kaihola
Anubhav Patel
Anudit Nagar
Anuj Godase
AQNOUCH Mohammed
AraHaan
arena
arenasys
Arindam Choudhury
Armin Ronacher
Arnon Yaari
Artem
Arun Babu Neelicattu
Ashley Manton
Ashwin Ramaswami
atse
Atsushi Odagiri
Avinash Karhana
Avner Cohen
Awit (Ah-Wit) Ghirmai
Baptiste Mispelon
Barney Gale
barneygale
Bartek Ogryczak
Bastian Venthur
Ben Bodenmiller
Ben Darnell
Ben Hoyt
Ben Mares
Ben Rosser
Bence Nagy
Benjamin Peterson
Benjamin VanEvery
Benoit Pierre
Berker Peksag
Bernard
Bernard Tyers
Bernardo B. Marques
Bernhard M. Wiedemann
Bertil Hatt
Bhavam Vidyarthi
Blazej Michalik
Bogdan Opanchuk
BorisZZZ
Brad Erickson
Bradley Ayers
Branch Vincent
Brandon L. Reiss
Brandt Bucher
Brannon Dorsey
Brett Randall
Brett Rosen
Brian Cristante
Brian Rosner
briantracy
BrownTruck
Bruno Oliveira
Bruno Renié
Bruno S
Bstrdsmkr
Buck Golemon
burrows
Bussonnier Matthias
bwoodsend
c22
Caleb Brown
Caleb Martinez
Calvin Smith
Carl Meyer
Carlos Liam
Carol Willing
Carter Thayer
Cass
Chandrasekhar Atina
Charlie Marsh
charwick
Chih-Hsuan Yen
Chris Brinker
Chris Hunt
Chris Jerdonek
Chris Kuehl
Chris Markiewicz
Chris McDonough
Chris Pawley
Chris Pryer
Chris Wolfe
Christian Clauss
Christian Heimes
Christian Oudard
Christoph Reiter
Christopher Hunt
Christopher Snyder
chrysle
cjc7373
Clark Boylan
Claudio Jolowicz
Clay McClure
Cody
Cody Soyland
Colin Watson
Collin Anderson
Connor Osborn
Cooper Lees
Cooper Ry Lees
Cory Benfield
Cory Wright
Craig Kerstiens
Cristian Sorinel
Cristina
Cristina Muñoz
ctg123
Curtis Doty
cytolentino
Daan De Meyer
Dale
Damian
Damian Quiroga
Damian Shaw
Dan Black
Dan Savilonis
Dan Sully
Dane Hillard
daniel
Daniel Collins
Daniel Hahler
Daniel Holth
Daniel Jost
Daniel Katz
Daniel Shaulov
Daniele Esposti
Daniele Nicolodi
Daniele Procida
Daniil Konovalenko
Danny Hermes
Danny McClanahan
Darren Kavanagh
Dav Clark
Dave Abrahams
Dave Jones
David Aguilar
David Black
David Bordeynik
David Caro
David D Lowe
David Evans
David Hewitt
David Linke
David Poggi
David Poznik
David Pursehouse
David Runge
David Tucker
David Wales
Davidovich
ddelange
Deepak Sharma
Deepyaman Datta
Denise Yu
dependabot[bot]
derwolfe
Desetude
Devesh Kumar Singh
devsagul
Diego Caraballo
Diego Ramirez
DiegoCaraballo
Dimitri Merejkowsky
Dimitri Papadopoulos
Dimitri Papadopoulos Orfanos
Dirk Stolle
Dmitry Gladkov
Dmitry Volodin
Domen Kožar
Dominic Davis-Foster
Donald Stufft
Dongweiming
doron zarhi
Dos Moonen
Douglas Thor
DrFeathers
Dustin Ingram
Dustin Rodrigues
Dwayne Bailey
Ed Morley
Edgar Ramírez
Edgar Ramírez Mondragón
Ee Durbin
Efflam Lemaillet
efflamlemaillet
Eitan Adler
ekristina
elainechan
Eli Schwartz
Elisha Hollander
Ellen Marie Dash
Emil Burzo
Emil Styrke
Emmanuel Arias
Endoh Takanao
enoch
Erdinc Mutlu
Eric Cousineau
Eric Gillingham
Eric Hanchrow
Eric Hopper
Erik M. Bray
Erik Rose
Erwin Janssen
Eugene Vereshchagin
everdimension
Federico
Felipe Peter
Felix Yan
fiber-space
Filip Kokosiński
Filipe Laíns
Finn Womack
finnagin
Flavio Amurrio
Florian Briand
Florian Rathgeber
Francesco
Francesco Montesano
Fredrik Orderud
Frost Ming
Gabriel Curio
Gabriel de Perthuis
Garry Polley
gavin
gdanielson
Geoffrey Sneddon
George Song
Georgi Valkov
Georgy Pchelkin
ghost
Giftlin Rajaiah
gizmoguy1
gkdoc
Godefroid Chapelle
Gopinath M
GOTO Hayato
gousaiyang
gpiks
Greg Roodt
Greg Ward
Guilherme Espada
Guillaume Seguin
gutsytechster
Guy Rozendorn
Guy Tuval
gzpan123
Hanjun Kim
Hari Charan
Harsh Vardhan
harupy
Harutaka Kawamura
hauntsaninja
Henrich Hartzer
Henry Schreiner
Herbert Pfennig
Holly Stotelmyer
Honnix
Hsiaoming Yang
Hugo Lopes Tavares
Hugo van Kemenade
Hugues Bruant
Hynek Schlawack
Ian Bicking
Ian Cordasco
Ian Lee
Ian Stapleton Cordasco
Ian Wienand
Igor Kuzmitshov
Igor Sobreira
Ikko Ashimine
Ilan Schnell
Illia Volochii
Ilya Baryshev
Inada Naoki
Ionel Cristian Mărieș
Ionel Maries Cristian
Itamar Turner-Trauring
Ivan Pozdeev
J. Nick Koston
Jacob Kim
Jacob Walls
Jaime Sanz
jakirkham
Jakub Kuczys
Jakub Stasiak
Jakub Vysoky
Jakub Wilk
James Cleveland
James Curtin
James Firth
James Gerity
James Polley
Jan Pokorný
Jannis Leidel
Jarek Potiuk
jarondl
Jason Curtis
Jason R. Coombs
JasonMo
JasonMo1
Jay Graves
Jean Abou Samra
Jean-Christophe Fillion-Robin
Jeff Barber
Jeff Dairiki
Jeff Widman
Jelmer Vernooij
jenix21
Jeremy Fleischman
Jeremy Stanley
Jeremy Zafran
Jesse Rittner
Jiashuo Li
Jim Fisher
Jim Garrison
Jinzhe Zeng
Jiun Bae
Jivan Amara
Joe Bylund
Joe Michelini
John Paton
John Sirois
John T. Wodder II
John-Scott Atlakson
johnthagen
Jon Banafato
Jon Dufresne
Jon Parise
Jonas Nockert
Jonathan Herbert
Joonatan Partanen
Joost Molenaar
Jorge Niedbalski
Joseph Bylund
Joseph Long
Josh Bronson
Josh Cannon
Josh Hansen
Josh Schneier
Joshua
JoshuaPerdue
Juan Luis Cano Rodríguez
Juanjo Bazán
Judah Rand
Julian Berman
Julian Gethmann
Julien Demoor
July Tikhonov
Jussi Kukkonen
Justin van Heek
jwg4
Jyrki Pulliainen
Kai Chen
Kai Mueller
Kamal Bin Mustafa
Karolina Surma
kasium
kaustav haldar
keanemind
Keith Maxwell
Kelsey Hightower
Kenneth Belitzky
Kenneth Reitz
Kevin Burke
Kevin Carter
Kevin Frommelt
Kevin R Patterson
Kexuan Sun
Kit Randel
Klaas van Schelven
KOLANICH
konstin
kpinc
Krishna Oza
Kumar McMillan
Kuntal Majumder
Kurt McKee
Kyle Persohn
lakshmanaram
Laszlo Kiss-Kollar
Laurent Bristiel
Laurent LAPORTE
Laurie O
Laurie Opperman
layday
Leon Sasson
Lev Givon
Lincoln de Sousa
Lipis
lorddavidiii
Loren Carvalho
Lucas Cimon
Ludovic Gasc
Luis Medel
Lukas Geiger
Lukas Juhrich
Luke Macken
Luo Jiebin
luojiebin
luz.paz
László Kiss Kollár
M00nL1ght
Marc Abramowitz
Marc Tamlyn
Marcus Smith
Mariatta
Mark Kohler
Mark McLoughlin
Mark Williams
Markus Hametner
Martey Dodoo
Martin Fischer
Martin Häcker
Martin Pavlasek
Masaki
Masklinn
Matej Stuchlik
Mathew Jennings
Mathieu Bridon
Mathieu Kniewallner
Matt Bacchi
Matt Good
Matt Maker
Matt Robenolt
Matt Wozniski
matthew
Matthew Einhorn
Matthew Feickert
Matthew Gilliard
Matthew Hughes
Matthew Iversen
Matthew Treinish
Matthew Trumbell
Matthew Willson
Matthias Bussonnier
mattip
Maurits van Rees
Max W Chase
Maxim Kurnikov
Maxime Rouyrre
mayeut
mbaluna
mdebi
memoselyk
meowmeowcat
Michael
Michael Aquilina
Michael E. Karpeles
Michael Klich
Michael Mintz
Michael Williamson
michaelpacer
Michał Górny
Mickaël Schoentgen
Miguel Araujo Perez
Mihir Singh
Mike
Mike Hendricks
Min RK
MinRK
Miro Hrončok
Monica Baluna
montefra
Monty Taylor
morotti
mrKazzila
Muha Ajjan
Nadav Wexler
Nahuel Ambrosini
Nate Coraor
Nate Prewitt
Nathan Houghton
Nathaniel J. Smith
Nehal J Wani
Neil Botelho
Nguyễn Gia Phong
Nicholas Serra
Nick Coghlan
Nick Stenning
Nick Timkovich
Nicolas Bock
Nicole Harris
Nikhil Benesch
Nikhil Ladha
Nikita Chepanov
Nikolay Korolev
Nipunn Koorapati
Nitesh Sharma
Niyas Sait
Noah
Noah Gorny
Nowell Strite
NtaleGrey
nvdv
OBITORASU
Ofek Lev
ofrinevo
Oliver Freund
Oliver Jeeves
Oliver Mannion
Oliver Tonnhofer
Olivier Girardot
Olivier Grisel
Ollie Rutherfurd
OMOTO Kenji
Omry Yadan
onlinejudge95
Oren Held
Oscar Benjamin
Oz N Tiram
Pachwenko
Patrick Dubroy
Patrick Jenkins
Patrick Lawson
patricktokeeffe
Patrik Kopkan
Paul Ganssle
Paul Kehrer
Paul Moore
Paul Nasrat
Paul Oswald
Paul van der Linden
Paulus Schoutsen
Pavel Safronov
Pavithra Eswaramoorthy
Pawel Jasinski
Paweł Szramowski
Pekka Klärck
Peter Gessler
Peter Lisák
Peter Shen
Peter Waller
Petr Viktorin
petr-tik
Phaneendra Chiruvella
Phil Elson
Phil Freo
Phil Pennock
Phil Whelan
Philip Jägenstedt
Philip Molloy
Philippe Ombredanne
Pi Delport
Pierre-Yves Rofes
Pieter Degroote
pip
Prabakaran Kumaresshan
Prabhjyotsing Surjit Singh Sodhi
Prabhu Marappan
Pradyun Gedam
Prashant Sharma
Pratik Mallya
pre-commit-ci[bot]
Preet Thakkar
Preston Holmes
Przemek Wrzos
Pulkit Goyal
q0w
Qiangning Hong
Qiming Xu
Quentin Lee
Quentin Pradet
R. David Murray
Rafael Caricio
Ralf Schmitt
Ran Benita
Randy Döring
Razzi Abuissa
rdb
Reece Dunham
Remi Rampin
Rene Dudfield
Riccardo Magliocchetti
Riccardo Schirone
Richard Jones
Richard Si
Ricky Ng-Adam
Rishi
rmorotti
RobberPhex
Robert Collins
Robert McGibbon
Robert Pollak
Robert T. McGibbon
robin elisha robinson
Roey Berman
Rohan Jain
Roman Bogorodskiy
Roman Donchenko
Romuald Brunet
ronaudinho
Ronny Pfannschmidt
Rory McCann
Ross Brattain
Roy Wellington Ⅳ
Ruairidh MacLeod
Russell Keith-Magee
Ryan Shepherd
Ryan Wooden
ryneeverett
S. Guliaev
Sachi King
Salvatore Rinchiera
sandeepkiran-js
Sander Van Balen
Savio Jomton
schlamar
Scott Kitterman
Sean
seanj
Sebastian Jordan
Sebastian Schaetz
Segev Finer
SeongSoo Cho
Sergey Vasilyev
Seth Michael Larson
Seth Woodworth
Shahar Epstein
Shantanu
shenxianpeng
shireenrao
Shivansh-007
Shixian Sheng
Shlomi Fish
Shovan Maity
Simeon Visser
Simon Cross
Simon Pichugin
sinoroc
sinscary
snook92
socketubs
Sorin Sbarnea
Srinivas Nyayapati
Srishti Hegde
Stavros Korokithakis
Stefan Scherfke
Stefano Rivera
Stephan Erb
Stephen Rosen
stepshal
Steve (Gadget) Barnes
Steve Barnes
Steve Dower
Steve Kowalik
Steven Myint
Steven Silvester
stonebig
studioj
Stéphane Bidoul
Stéphane Bidoul (ACSONE)
Stéphane Klein
Sumana Harihareswara
Surbhi Sharma
Sviatoslav Sydorenko
Sviatoslav Sydorenko (Святослав Сидоренко)
Swat009
Sylvain
Takayuki SHIMIZUKAWA
Taneli Hukkinen
tbeswick
Thiago
Thijs Triemstra
Thomas Fenzl
Thomas Grainger
Thomas Guettler
Thomas Johansson
Thomas Kluyver
Thomas Smith
Thomas VINCENT
Tim D. Smith
Tim Gates
Tim Harder
Tim Heap
tim smith
tinruufu
Tobias Hermann
Tom Forbes
Tom Freudenheim
Tom V
Tomas Hrnciar
Tomas Orsava
Tomer Chachamu
Tommi Enenkel | AnB
Tomáš Hrnčiar
Tony Beswick
Tony Narlock
Tony Zhaocheng Tan
TonyBeswick
toonarmycaptain
Toshio Kuratomi
toxinu
Travis Swicegood
Tushar Sadhwani
Tzu-ping Chung
Valentin Haenel
Victor Stinner
victorvpaulo
Vikram - Google
Viktor Szépe
Ville Skyttä
Vinay Sajip
Vincent Philippon
Vinicyus Macedo
Vipul Kumar
Vitaly Babiy
Vladimir Fokow
Vladimir Rutsky
W. Trevor King
Wil Tan
Wilfred Hughes
William Edwards
William ML Leslie
William T Olson
William Woodruff
Wilson Mo
wim glenn
Winson Luk
Wolfgang Maier
Wu Zhenyu
XAMES3
Xavier Fernandez
Xianpeng Shen
xoviat
xtreak
YAMAMOTO Takashi
Yen Chi Hsuan
Yeray Diaz Diaz
Yoval P
Yu Jian
Yuan Jing Vincent Yan
Yusuke Hayashi
Zearin
Zhiping Deng
ziebam
Zvezdan Petkovic
Łukasz Langa
Роман Донченко
Семён Марьясин
@@ -1,11 +1,10 @@
Metadata-Version: 2.1 Metadata-Version: 2.2
Name: pip Name: pip
Version: 22.2.1 Version: 25.0.1
Summary: The PyPA recommended tool for installing Python packages. Summary: The PyPA recommended tool for installing Python packages.
Home-page: https://pip.pypa.io/ Author-email: The pip developers <distutils-sig@python.org>
Author: The pip developers
Author-email: distutils-sig@python.org
License: MIT License: MIT
Project-URL: Homepage, https://pip.pypa.io/
Project-URL: Documentation, https://pip.pypa.io Project-URL: Documentation, https://pip.pypa.io
Project-URL: Source, https://github.com/pypa/pip Project-URL: Source, https://github.com/pypa/pip
Project-URL: Changelog, https://pip.pypa.io/en/stable/news/ Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
@@ -16,24 +15,35 @@ Classifier: Topic :: Software Development :: Build Tools
Classifier: Programming Language :: Python Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.7 Requires-Python: >=3.8
Description-Content-Type: text/x-rst
License-File: LICENSE.txt License-File: LICENSE.txt
License-File: AUTHORS.txt
pip - The Python Package Installer pip - The Python Package Installer
================================== ==================================
.. image:: https://img.shields.io/pypi/v/pip.svg .. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg
:target: https://pypi.org/project/pip/ :target: https://pypi.org/project/pip/
:alt: PyPI
.. image:: https://readthedocs.org/projects/pip/badge/?version=latest .. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip
:target: https://pypi.org/project/pip
:alt: PyPI - Python Version
.. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest
:target: https://pip.pypa.io/en/latest :target: https://pip.pypa.io/en/latest
:alt: Documentation
|pypi-version| |python-versions| |docs-badge|
pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
@@ -47,10 +57,6 @@ We release updates regularly, with a new version every 3 months. Find more detai
* `Release notes`_ * `Release notes`_
* `Release process`_ * `Release process`_
In pip 20.3, we've `made a big improvement to the heart of pip`_; `learn more`_. We want your input, so `sign up for our user experience research studies`_ to help us do it right.
**Note**: pip 21.0, in January 2021, removed Python 2 support, per pip's `Python 2 support policy`_. Please migrate to Python 3.
If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms: If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
* `Issue tracking`_ * `Issue tracking`_
@@ -61,7 +67,6 @@ If you want to get involved head over to GitHub to get the source code, look at
* `GitHub page`_ * `GitHub page`_
* `Development documentation`_ * `Development documentation`_
* `Development mailing list`_
* `Development IRC`_ * `Development IRC`_
Code of Conduct Code of Conduct
@@ -78,13 +83,8 @@ rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
.. _Release process: https://pip.pypa.io/en/latest/development/release-process/ .. _Release process: https://pip.pypa.io/en/latest/development/release-process/
.. _GitHub page: https://github.com/pypa/pip .. _GitHub page: https://github.com/pypa/pip
.. _Development documentation: https://pip.pypa.io/en/latest/development .. _Development documentation: https://pip.pypa.io/en/latest/development
.. _made a big improvement to the heart of pip: https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html
.. _learn more: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020
.. _sign up for our user experience research studies: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html
.. _Python 2 support policy: https://pip.pypa.io/en/latest/development/release-process/#python-2-support
.. _Issue tracking: https://github.com/pypa/pip/issues .. _Issue tracking: https://github.com/pypa/pip/issues
.. _Discourse channel: https://discuss.python.org/c/packaging .. _Discourse channel: https://discuss.python.org/c/packaging
.. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/
.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa .. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev .. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md .. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
@@ -0,0 +1,854 @@
../../Scripts/pip.exe,sha256=TWiJ5FcJI2RNY2D9Eq2Vpk8aawbkJwUoQGIH4xe81k4,108405
../../Scripts/pip3.10.exe,sha256=TWiJ5FcJI2RNY2D9Eq2Vpk8aawbkJwUoQGIH4xe81k4,108405
../../Scripts/pip3.exe,sha256=TWiJ5FcJI2RNY2D9Eq2Vpk8aawbkJwUoQGIH4xe81k4,108405
pip-25.0.1.dist-info/AUTHORS.txt,sha256=HqzpBVLfT1lBthqQfiDlVeFkg65hJ7ZQvvWhoq-BAsA,11018
pip-25.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pip-25.0.1.dist-info/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
pip-25.0.1.dist-info/METADATA,sha256=T6cxjPMPl523zsRcEsu8K0-IoV8S7vv1mmKR0KA6-SY,3677
pip-25.0.1.dist-info/RECORD,,
pip-25.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip-25.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
pip-25.0.1.dist-info/entry_points.txt,sha256=eeIjuzfnfR2PrhbjnbzFU6MnSS70kZLxwaHHq6M-bD0,87
pip-25.0.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pip/__init__.py,sha256=aKiv_sTe7UbE7qmtCinJutFjqN0MndZQZ1fKLNwFFLE,357
pip/__main__.py,sha256=WzbhHXTbSE6gBY19mNN9m4s5o_365LOvTYSgqgbdBhE,854
pip/__pip-runner__.py,sha256=cPPWuJ6NK_k-GzfvlejLFgwzmYUROmpAR6QC3Q-vkXQ,1450
pip/__pycache__/__init__.cpython-310.pyc,,
pip/__pycache__/__main__.cpython-310.pyc,,
pip/__pycache__/__pip-runner__.cpython-310.pyc,,
pip/_internal/__init__.py,sha256=MfcoOluDZ8QMCFYal04IqOJ9q6m2V7a0aOsnI-WOxUo,513
pip/_internal/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/__pycache__/build_env.cpython-310.pyc,,
pip/_internal/__pycache__/cache.cpython-310.pyc,,
pip/_internal/__pycache__/configuration.cpython-310.pyc,,
pip/_internal/__pycache__/exceptions.cpython-310.pyc,,
pip/_internal/__pycache__/main.cpython-310.pyc,,
pip/_internal/__pycache__/pyproject.cpython-310.pyc,,
pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc,,
pip/_internal/__pycache__/wheel_builder.cpython-310.pyc,,
pip/_internal/build_env.py,sha256=Dv4UCClSg4uNaal_hL-trg5-zl3Is9CuIDxkChCkXF4,10700
pip/_internal/cache.py,sha256=Jb698p5PNigRtpW5o26wQNkkUv4MnQ94mc471wL63A0,10369
pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132
pip/_internal/cli/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc,,
pip/_internal/cli/__pycache__/base_command.cpython-310.pyc,,
pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc,,
pip/_internal/cli/__pycache__/command_context.cpython-310.pyc,,
pip/_internal/cli/__pycache__/index_command.cpython-310.pyc,,
pip/_internal/cli/__pycache__/main.cpython-310.pyc,,
pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc,,
pip/_internal/cli/__pycache__/parser.cpython-310.pyc,,
pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc,,
pip/_internal/cli/__pycache__/req_command.cpython-310.pyc,,
pip/_internal/cli/__pycache__/spinners.cpython-310.pyc,,
pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc,,
pip/_internal/cli/autocompletion.py,sha256=Lli3Mr6aDNu7ZkJJFFvwD2-hFxNI6Avz8OwMyS5TVrs,6865
pip/_internal/cli/base_command.py,sha256=NZin6KMzW9NSYzKk4Tc8isb_TQYKR4CKd5j9mSm46PI,8625
pip/_internal/cli/cmdoptions.py,sha256=V3BB22F4_v_RkHaZ5onWnszhbBtjYZvNhbn9M0NO0HI,30116
pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774
pip/_internal/cli/index_command.py,sha256=i_sgNlPmXC5iHUaY-dmmrHKKTgc5O4hWzisr5Al1rr0,5677
pip/_internal/cli/main.py,sha256=BDZef-bWe9g9Jpr4OVs4dDf-845HJsKw835T7AqEnAc,2817
pip/_internal/cli/main_parser.py,sha256=laDpsuBDl6kyfywp9eMMA9s84jfH2TJJn-vmL0GG90w,4338
pip/_internal/cli/parser.py,sha256=VCMtduzECUV87KaHNu-xJ-wLNL82yT3x16V4XBxOAqI,10825
pip/_internal/cli/progress_bars.py,sha256=9GcgusWtwfqou2zhAQp1XNbQHIDslqyyz9UwLzw7Jgc,2717
pip/_internal/cli/req_command.py,sha256=DqeFhmUMs6o6Ev8qawAcOoYNdAZsfyKS0MZI5jsJYwQ,12250
pip/_internal/cli/spinners.py,sha256=hIJ83GerdFgFCdobIA23Jggetegl_uC4Sp586nzFbPE,5118
pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116
pip/_internal/commands/__init__.py,sha256=5oRO9O3dM2vGuh0bFw4HOVletryrz5HHMmmPWwJrH9U,3882
pip/_internal/commands/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/commands/__pycache__/cache.cpython-310.pyc,,
pip/_internal/commands/__pycache__/check.cpython-310.pyc,,
pip/_internal/commands/__pycache__/completion.cpython-310.pyc,,
pip/_internal/commands/__pycache__/configuration.cpython-310.pyc,,
pip/_internal/commands/__pycache__/debug.cpython-310.pyc,,
pip/_internal/commands/__pycache__/download.cpython-310.pyc,,
pip/_internal/commands/__pycache__/freeze.cpython-310.pyc,,
pip/_internal/commands/__pycache__/hash.cpython-310.pyc,,
pip/_internal/commands/__pycache__/help.cpython-310.pyc,,
pip/_internal/commands/__pycache__/index.cpython-310.pyc,,
pip/_internal/commands/__pycache__/inspect.cpython-310.pyc,,
pip/_internal/commands/__pycache__/install.cpython-310.pyc,,
pip/_internal/commands/__pycache__/list.cpython-310.pyc,,
pip/_internal/commands/__pycache__/search.cpython-310.pyc,,
pip/_internal/commands/__pycache__/show.cpython-310.pyc,,
pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc,,
pip/_internal/commands/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/commands/cache.py,sha256=IOezTicHjGE5sWdBx2nwPVgbjuJHM3s-BZEkpZLemuY,8107
pip/_internal/commands/check.py,sha256=Hr_4eiMd9cgVDgEvjtIdw915NmL7ROIWW8enkr8slPQ,2268
pip/_internal/commands/completion.py,sha256=HT4lD0bgsflHq2IDgYfiEdp7IGGtE7s6MgI3xn0VQEw,4287
pip/_internal/commands/configuration.py,sha256=n98enwp6y0b5G6fiRQjaZo43FlJKYve_daMhN-4BRNc,9766
pip/_internal/commands/debug.py,sha256=DNDRgE9YsKrbYzU0s3VKi8rHtKF4X13CJ_br_8PUXO0,6797
pip/_internal/commands/download.py,sha256=0qB0nys6ZEPsog451lDsjL5Bx7Z97t-B80oFZKhpzKM,5273
pip/_internal/commands/freeze.py,sha256=2Vt72BYTSm9rzue6d8dNzt8idxWK4Db6Hd-anq7GQ80,3203
pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703
pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132
pip/_internal/commands/index.py,sha256=RAXxmJwFhVb5S1BYzb5ifX3sn9Na8v2CCVYwSMP8pao,4731
pip/_internal/commands/inspect.py,sha256=PGrY9TRTRCM3y5Ml8Bdk8DEOXquWRfscr4DRo1LOTPc,3189
pip/_internal/commands/install.py,sha256=r3yHQUxvxt7gD5j9n6zRDslAvtx9CT_whLuQJcktp6M,29390
pip/_internal/commands/list.py,sha256=oiIzSjLP6__d7dIS3q0Xb5ywsaOThBWRqMyjjKzkPdM,12769
pip/_internal/commands/search.py,sha256=fWkUQVx_gm8ebbFAlCgqtxKXT9rNahpJ-BI__3HNZpg,5626
pip/_internal/commands/show.py,sha256=0YBhCga3PAd81vT3l7UWflktSpB5-aYqQcJxBVPazVM,7857
pip/_internal/commands/uninstall.py,sha256=7pOR7enK76gimyxQbzxcG1OsyLXL3DvX939xmM8Fvtg,3892
pip/_internal/commands/wheel.py,sha256=eJRhr_qoNNxWAkkdJCNiQM7CXd4E1_YyQhsqJnBPGGg,6414
pip/_internal/configuration.py,sha256=-KOok6jh3hFzXMPQFPJ1_EFjBpAsge-RSreQuLHLmzo,14005
pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/base.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/installed.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc,,
pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/distributions/base.py,sha256=QeB9qvKXDIjLdPBDE5fMgpfGqMMCr-govnuoQnGuiF8,1783
pip/_internal/distributions/installed.py,sha256=QinHFbWAQ8oE0pbD8MFZWkwlnfU1QYTccA1vnhrlYOU,842
pip/_internal/distributions/sdist.py,sha256=PlcP4a6-R6c98XnOM-b6Lkb3rsvh9iG4ok8shaanrzs,6751
pip/_internal/distributions/wheel.py,sha256=THBYfnv7VVt8mYhMYUtH13S1E7FDwtDyDfmUcl8ai0E,1317
pip/_internal/exceptions.py,sha256=2_byISIv3kSnI_9T-Esfxrt0LnTRgcUHyxu0twsHjQY,26481
pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30
pip/_internal/index/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/index/__pycache__/collector.cpython-310.pyc,,
pip/_internal/index/__pycache__/package_finder.cpython-310.pyc,,
pip/_internal/index/__pycache__/sources.cpython-310.pyc,,
pip/_internal/index/collector.py,sha256=RdPO0JLAlmyBWPAWYHPyRoGjz3GNAeTngCNkbGey_mE,16265
pip/_internal/index/package_finder.py,sha256=mJHAljlHeHuclyuxtjvBZO6DtovKjsZjF_tCh_wux5E,38076
pip/_internal/index/sources.py,sha256=lPBLK5Xiy8Q6IQMio26Wl7ocfZOKkgGklIBNyUJ23fI,8632
pip/_internal/locations/__init__.py,sha256=UaAxeZ_f93FyouuFf4p7SXYF-4WstXuEvd3LbmPCAno,14925
pip/_internal/locations/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc,,
pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc,,
pip/_internal/locations/__pycache__/base.cpython-310.pyc,,
pip/_internal/locations/_distutils.py,sha256=x6nyVLj7X11Y4khIdf-mFlxMl2FWadtVEgeb8upc_WI,6013
pip/_internal/locations/_sysconfig.py,sha256=IGzds60qsFneRogC-oeBaY7bEh3lPt_v47kMJChQXsU,7724
pip/_internal/locations/base.py,sha256=RQiPi1d4FVM2Bxk04dQhXZ2PqkeljEL2fZZ9SYqIQ78,2556
pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340
pip/_internal/metadata/__init__.py,sha256=CU8jK1TZso7jOLdr0sX9xDjrcs5iy8d7IRK-hvaIO5Y,4337
pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/metadata/__pycache__/_json.cpython-310.pyc,,
pip/_internal/metadata/__pycache__/base.cpython-310.pyc,,
pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc,,
pip/_internal/metadata/_json.py,sha256=ezrIYazHCINM2QUk1eA9wEAMj3aeGWeDVgGalgUzKpc,2707
pip/_internal/metadata/base.py,sha256=ft0K5XNgI4ETqZnRv2-CtvgYiMOMAeGMAzxT-f6VLJA,25298
pip/_internal/metadata/importlib/__init__.py,sha256=jUUidoxnHcfITHHaAWG1G2i5fdBYklv_uJcjo2x7VYE,135
pip/_internal/metadata/importlib/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/metadata/importlib/__pycache__/_compat.cpython-310.pyc,,
pip/_internal/metadata/importlib/__pycache__/_dists.cpython-310.pyc,,
pip/_internal/metadata/importlib/__pycache__/_envs.cpython-310.pyc,,
pip/_internal/metadata/importlib/_compat.py,sha256=c6av8sP8BBjAZuFSJow1iWfygUXNM3xRTCn5nqw6B9M,2796
pip/_internal/metadata/importlib/_dists.py,sha256=ftmYiyfUGUIjnVwt6W-Ijsimy5c28KgmXly5Q5IQ2P4,8279
pip/_internal/metadata/importlib/_envs.py,sha256=UUB980XSrDWrMpQ1_G45i0r8Hqlg_tg3IPQ63mEqbNc,7431
pip/_internal/metadata/pkg_resources.py,sha256=U07ETAINSGeSRBfWUG93E4tZZbaW_f7PGzEqZN0hulc,10542
pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63
pip/_internal/models/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/models/__pycache__/candidate.cpython-310.pyc,,
pip/_internal/models/__pycache__/direct_url.cpython-310.pyc,,
pip/_internal/models/__pycache__/format_control.cpython-310.pyc,,
pip/_internal/models/__pycache__/index.cpython-310.pyc,,
pip/_internal/models/__pycache__/installation_report.cpython-310.pyc,,
pip/_internal/models/__pycache__/link.cpython-310.pyc,,
pip/_internal/models/__pycache__/scheme.cpython-310.pyc,,
pip/_internal/models/__pycache__/search_scope.cpython-310.pyc,,
pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc,,
pip/_internal/models/__pycache__/target_python.cpython-310.pyc,,
pip/_internal/models/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/models/candidate.py,sha256=zzgFRuw_kWPjKpGw7LC0ZUMD2CQ2EberUIYs8izjdCA,753
pip/_internal/models/direct_url.py,sha256=uBtY2HHd3TO9cKQJWh0ThvE5FRr-MWRYChRU4IG9HZE,6578
pip/_internal/models/format_control.py,sha256=wtsQqSK9HaUiNxQEuB-C62eVimw6G4_VQFxV9-_KDBE,2486
pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
pip/_internal/models/installation_report.py,sha256=zRVZoaz-2vsrezj_H3hLOhMZCK9c7TbzWgC-jOalD00,2818
pip/_internal/models/link.py,sha256=GQ8hq7x-FDFPv25Nbn2veIM-MlBrGZDGLd7aZeF4Xrg,21448
pip/_internal/models/scheme.py,sha256=PakmHJM3e8OOWSZFtfz1Az7f1meONJnkGuQxFlt3wBE,575
pip/_internal/models/search_scope.py,sha256=67NEnsYY84784S-MM7ekQuo9KXLH-7MzFntXjapvAo0,4531
pip/_internal/models/selection_prefs.py,sha256=qaFfDs3ciqoXPg6xx45N1jPLqccLJw4N0s4P0PyHTQ8,2015
pip/_internal/models/target_python.py,sha256=2XaH2rZ5ZF-K5wcJbEMGEl7SqrTToDDNkrtQ2v_v_-Q,4271
pip/_internal/models/wheel.py,sha256=G7dND_s4ebPkEL7RJ1qCY0QhUUWIIK6AnjWgRATF5no,4539
pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50
pip/_internal/network/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/network/__pycache__/auth.cpython-310.pyc,,
pip/_internal/network/__pycache__/cache.cpython-310.pyc,,
pip/_internal/network/__pycache__/download.cpython-310.pyc,,
pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc,,
pip/_internal/network/__pycache__/session.cpython-310.pyc,,
pip/_internal/network/__pycache__/utils.cpython-310.pyc,,
pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc,,
pip/_internal/network/auth.py,sha256=D4gASjUrqoDFlSt6gQ767KAAjv6PUyJU0puDlhXNVRE,20809
pip/_internal/network/cache.py,sha256=0yGMA3Eet59xBSLtbPAenvI53dl29oUOeqZ2c0QL2Ss,4614
pip/_internal/network/download.py,sha256=FLOP29dPYECBiAi7eEjvAbNkyzaKNqbyjOT2m8HPW8U,6048
pip/_internal/network/lazy_wheel.py,sha256=PBdoMoNQQIA84Fhgne38jWF52W4x_KtsHjxgv4dkRKA,7622
pip/_internal/network/session.py,sha256=msM4es16LmmNEYNkrYyg8fTc7gAHbKFltawfKP27LOI,18771
pip/_internal/network/utils.py,sha256=Inaxel-NxBu4PQWkjyErdnfewsFCcgHph7dzR1-FboY,4088
pip/_internal/network/xmlrpc.py,sha256=sAxzOacJ-N1NXGPvap9jC3zuYWSnnv3GXtgR2-E2APA,1838
pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/operations/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/operations/__pycache__/check.cpython-310.pyc,,
pip/_internal/operations/__pycache__/freeze.cpython-310.pyc,,
pip/_internal/operations/__pycache__/prepare.cpython-310.pyc,,
pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/build_tracker.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc,,
pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc,,
pip/_internal/operations/build/build_tracker.py,sha256=-ARW_TcjHCOX7D2NUOGntB4Fgc6b4aolsXkAK6BWL7w,4774
pip/_internal/operations/build/metadata.py,sha256=9S0CUD8U3QqZeXp-Zyt8HxwU90lE4QrnYDgrqZDzBnc,1422
pip/_internal/operations/build/metadata_editable.py,sha256=xlAwcP9q_8_fmv_3I39w9EZ7SQV9hnJZr9VuTsq2Y68,1510
pip/_internal/operations/build/metadata_legacy.py,sha256=8i6i1QZX9m_lKPStEFsHKM0MT4a-CD408JOw99daLmo,2190
pip/_internal/operations/build/wheel.py,sha256=sT12FBLAxDC6wyrDorh8kvcZ1jG5qInCRWzzP-UkJiQ,1075
pip/_internal/operations/build/wheel_editable.py,sha256=yOtoH6zpAkoKYEUtr8FhzrYnkNHQaQBjWQ2HYae1MQg,1417
pip/_internal/operations/build/wheel_legacy.py,sha256=K-6kNhmj-1xDF45ny1yheMerF0ui4EoQCLzEoHh6-tc,3045
pip/_internal/operations/check.py,sha256=L24vRL8VWbyywdoeAhM89WCd8zLTnjIbULlKelUgIec,5912
pip/_internal/operations/freeze.py,sha256=1_M79jAQKnCxWr-KCCmHuVXOVFGaUJHmoWLfFzgh7K4,9843
pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51
pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc,,
pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/operations/install/editable_legacy.py,sha256=PoEsNEPGbIZ2yQphPsmYTKLOCMs4gv5OcCdzW124NcA,1283
pip/_internal/operations/install/wheel.py,sha256=X5Iz9yUg5LlK5VNQ9g2ikc6dcRu8EPi_SUi5iuEDRgo,27615
pip/_internal/operations/prepare.py,sha256=joWJwPkuqGscQgVNImLK71e9hRapwKvRCM8HclysmvU,28118
pip/_internal/pyproject.py,sha256=GLJ6rWRS5_2noKdajohoLyDty57Z7QXhcUAYghmTnWc,7286
pip/_internal/req/__init__.py,sha256=HxBFtZy_BbCclLgr26waMtpzYdO5T3vxePvpGAXSt5s,2653
pip/_internal/req/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/req/__pycache__/constructors.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_file.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_install.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_set.cpython-310.pyc,,
pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc,,
pip/_internal/req/constructors.py,sha256=v1qzCN1mIldwx-nCrPc8JO4lxkm3Fv8M5RWvt8LISjc,18430
pip/_internal/req/req_file.py,sha256=eys82McgaICOGic2UZRHjD720piKJPwmeSYdXlWwl6w,20234
pip/_internal/req/req_install.py,sha256=BMptxHYg2uG_b-7HFEULPb3nuw0FMAbuea8zTq2rE7w,35786
pip/_internal/req/req_set.py,sha256=j3esG0s6SzoVReX9rWn4rpYNtyET_fwxbwJPRimvRxo,2858
pip/_internal/req/req_uninstall.py,sha256=qzDIxJo-OETWqGais7tSMCDcWbATYABT-Tid3ityF0s,23853
pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/resolution/__pycache__/base.cpython-310.pyc,,
pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583
pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc,,
pip/_internal/resolution/legacy/resolver.py,sha256=3HZiJBRd1FTN6jQpI4qRO8-TbLYeIbUTS6PFvXnXs2w,24068
pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc,,
pip/_internal/resolution/resolvelib/base.py,sha256=DCf669FsqyQY5uqXeePDHQY1e4QO-pBzWH8O0s9-K94,5023
pip/_internal/resolution/resolvelib/candidates.py,sha256=5UZ1upNnmqsP-nmEZaDYxaBgCoejw_e2WVGmmAvBxXc,20001
pip/_internal/resolution/resolvelib/factory.py,sha256=MJOLSZJY8_28PPdcutoQ6gjJ_1eBDt6Z1edtfTJyR4E,32659
pip/_internal/resolution/resolvelib/found_candidates.py,sha256=9hrTyQqFvl9I7Tji79F1AxHv39Qh1rkJ_7deSHSMfQc,6383
pip/_internal/resolution/resolvelib/provider.py,sha256=bcsFnYvlmtB80cwVdW1fIwgol8ZNr1f1VHyRTkz47SM,9935
pip/_internal/resolution/resolvelib/reporter.py,sha256=00JtoXEkTlw0-rl_sl54d71avwOsJHt9GGHcrj5Sza0,3168
pip/_internal/resolution/resolvelib/requirements.py,sha256=7JG4Z72e5Yk4vU0S5ulGvbqTy4FMQGYhY5zQhX9zTtY,8065
pip/_internal/resolution/resolvelib/resolver.py,sha256=nLJOsVMEVi2gQUVJoUFKMZAeu2f7GRMjGMvNSWyz0Bc,12592
pip/_internal/self_outdated_check.py,sha256=1PFtttvLAeyCVR3tPoBq2sOlPD0IJ-KSqU6bc1HUk9c,8318
pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_internal/utils/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/utils/__pycache__/_jaraco_text.cpython-310.pyc,,
pip/_internal/utils/__pycache__/_log.cpython-310.pyc,,
pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc,,
pip/_internal/utils/__pycache__/compat.cpython-310.pyc,,
pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc,,
pip/_internal/utils/__pycache__/datetime.cpython-310.pyc,,
pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc,,
pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc,,
pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc,,
pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc,,
pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc,,
pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc,,
pip/_internal/utils/__pycache__/glibc.cpython-310.pyc,,
pip/_internal/utils/__pycache__/hashes.cpython-310.pyc,,
pip/_internal/utils/__pycache__/logging.cpython-310.pyc,,
pip/_internal/utils/__pycache__/misc.cpython-310.pyc,,
pip/_internal/utils/__pycache__/packaging.cpython-310.pyc,,
pip/_internal/utils/__pycache__/retry.cpython-310.pyc,,
pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc,,
pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc,,
pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc,,
pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc,,
pip/_internal/utils/__pycache__/urls.cpython-310.pyc,,
pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc,,
pip/_internal/utils/__pycache__/wheel.cpython-310.pyc,,
pip/_internal/utils/_jaraco_text.py,sha256=M15uUPIh5NpP1tdUGBxRau6q1ZAEtI8-XyLEETscFfE,3350
pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665
pip/_internal/utils/compat.py,sha256=ckkFveBiYQjRWjkNsajt_oWPS57tJvE8XxoC4OIYgCY,2399
pip/_internal/utils/compatibility_tags.py,sha256=OWq5axHpW-MEEPztGdvgADrgJPAcV9a88Rxm4Z8VBs8,6272
pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242
pip/_internal/utils/deprecation.py,sha256=k7Qg_UBAaaTdyq82YVARA6D7RmcGTXGv7fnfcgigj4Q,3707
pip/_internal/utils/direct_url_helpers.py,sha256=r2MRtkVDACv9AGqYODBUC9CjwgtsUU1s68hmgfCJMtA,3196
pip/_internal/utils/egg_link.py,sha256=0FePZoUYKv4RGQ2t6x7w5Z427wbA_Uo3WZnAkrgsuqo,2463
pip/_internal/utils/entrypoints.py,sha256=YlhLTRl2oHBAuqhc-zmL7USS67TPWVHImjeAQHreZTQ,3064
pip/_internal/utils/filesystem.py,sha256=ajvA-q4ocliW9kPp8Yquh-4vssXbu-UKbo5FV9V4X64,4950
pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716
pip/_internal/utils/glibc.py,sha256=vUkWq_1pJuzcYNcGKLlQmABoUiisK8noYY1yc8Wq4w4,3734
pip/_internal/utils/hashes.py,sha256=XGGLL0AG8-RhWnyz87xF6MFZ--BKadHU35D47eApCKI,4972
pip/_internal/utils/logging.py,sha256=ONfbrhaD248akkosK79if97n20EABxwjOxp5dE5RCRY,11845
pip/_internal/utils/misc.py,sha256=DWnYxBUItjRp7hhxEg4ih6P6YpKrykM86dbi_EcU8SQ,23450
pip/_internal/utils/packaging.py,sha256=cm-X_0HVHV_jRwUVZh6AuEWqSitzf8EpaJ7Uv2UGu6A,2142
pip/_internal/utils/retry.py,sha256=mhFbykXjhTnZfgzeuy-vl9c8nECnYn_CMtwNJX2tYzQ,1392
pip/_internal/utils/setuptools_build.py,sha256=ouXpud-jeS8xPyTPsXJ-m34NPvK5os45otAzdSV_IJE,4435
pip/_internal/utils/subprocess.py,sha256=EsvqSRiSMHF98T8Txmu6NLU3U--MpTTQjtNgKP0P--M,8988
pip/_internal/utils/temp_dir.py,sha256=5qOXe8M4JeY6vaFQM867d5zkp1bSwMZ-KT5jymmP0Zg,9310
pip/_internal/utils/unpacking.py,sha256=_gVdyzTRDMYktpnYljn4OoxrZTtMCf4xknSm4rK0WaA,11967
pip/_internal/utils/urls.py,sha256=qceSOZb5lbNDrHNsv7_S4L4Ytszja5NwPKUMnZHbYnM,1599
pip/_internal/utils/virtualenv.py,sha256=S6f7csYorRpiD6cvn3jISZYc3I8PJC43H5iMFpRAEDU,3456
pip/_internal/utils/wheel.py,sha256=b442jkydFHjXzDy6cMR7MpzWBJ1Q82hR5F33cmcHV3g,4494
pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/git.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc,,
pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc,,
pip/_internal/vcs/bazaar.py,sha256=EKStcQaKpNu0NK4p5Q10Oc4xb3DUxFw024XrJy40bFQ,3528
pip/_internal/vcs/git.py,sha256=3tpc9LQA_J4IVW5r5NvWaaSeDzcmJOrSFZN0J8vIKfU,18177
pip/_internal/vcs/mercurial.py,sha256=oULOhzJ2Uie-06d1omkL-_Gc6meGaUkyogvqG9ZCyPs,5249
pip/_internal/vcs/subversion.py,sha256=ddTugHBqHzV3ebKlU5QXHPN4gUqlyXbOx8q8NgXKvs8,11735
pip/_internal/vcs/versioncontrol.py,sha256=cvf_-hnTAjQLXJ3d17FMNhQfcO1AcKWUF10tfrYyP-c,22440
pip/_internal/wheel_builder.py,sha256=DL3A8LKeRj_ACp11WS5wSgASgPFqeyAeXJKdXfmaWXU,11799
pip/_vendor/__init__.py,sha256=JYuAXvClhInxIrA2FTp5p-uuWVL7WV6-vEpTs46-Qh4,4873
pip/_vendor/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/__pycache__/typing_extensions.cpython-310.pyc,,
pip/_vendor/cachecontrol/__init__.py,sha256=LMC5CBe94ZRL5xhlzwyPDmHXvBD0p7lT4R3Z73D6a_I,677
pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc,,
pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc,,
pip/_vendor/cachecontrol/_cmd.py,sha256=iist2EpzJvDVIhMAxXq8iFnTBsiZAd6iplxfmNboNyk,1737
pip/_vendor/cachecontrol/adapter.py,sha256=febjY4LV87iiCIK3jcl8iH58iaSA7b9WkovsByIDK0Y,6348
pip/_vendor/cachecontrol/cache.py,sha256=OXwv7Fn2AwnKNiahJHnjtvaKLndvVLv_-zO-ltlV9qI,1953
pip/_vendor/cachecontrol/caches/__init__.py,sha256=dtrrroK5BnADR1GWjCZ19aZ0tFsMfvFBtLQQU1sp_ag,303
pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc,,
pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc,,
pip/_vendor/cachecontrol/caches/file_cache.py,sha256=b7oMgsRSqPmEsonVJw6uFEYUlFgD6GF8TyacOGG1x3M,5399
pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=9rmqwtYu_ljVkW6_oLqbC7EaX_a8YT_yLuna-eS0dgo,1386
pip/_vendor/cachecontrol/controller.py,sha256=glbPj2iZlGqdBg8z09D2DtQOzoOGXnWvy7K2LEyBsEQ,18576
pip/_vendor/cachecontrol/filewrapper.py,sha256=2ktXNPE0KqnyzF24aOsKCA58HQq1xeC6l2g6_zwjghc,4291
pip/_vendor/cachecontrol/heuristics.py,sha256=gqMXU8w0gQuEQiSdu3Yg-0vd9kW7nrWKbLca75rheGE,4881
pip/_vendor/cachecontrol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/cachecontrol/serialize.py,sha256=HQd2IllQ05HzPkVLMXTF2uX5mjEQjDBkxCqUJUODpZk,5163
pip/_vendor/cachecontrol/wrapper.py,sha256=hsGc7g8QGQTT-4f8tgz3AM5qwScg6FO0BSdLSRdEvpU,1417
pip/_vendor/certifi/__init__.py,sha256=p_GYZrjUwPBUhpLlCZoGb0miKBKSqDAyZC5DvIuqbHQ,94
pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/certifi/__pycache__/core.cpython-310.pyc,,
pip/_vendor/certifi/cacert.pem,sha256=lO3rZukXdPyuk6BWUJFOKQliWaXH6HGh9l1GGrUgG0c,299427
pip/_vendor/certifi/core.py,sha256=2SRT5rIcQChFDbe37BQa-kULxAgJ8qN6l1jfqTp4HIs,4486
pip/_vendor/certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/distlib/__init__.py,sha256=dcwgYGYGQqAEawBXPDtIx80DO_3cOmFv8HTc8JMzknQ,625
pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/database.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/index.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/util.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/version.cpython-310.pyc,,
pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc,,
pip/_vendor/distlib/compat.py,sha256=2jRSjRI4o-vlXeTK2BCGIUhkc6e9ZGhSsacRM5oseTw,41467
pip/_vendor/distlib/database.py,sha256=mHy_LxiXIsIVRb-T0-idBrVLw3Ffij5teHCpbjmJ9YU,51160
pip/_vendor/distlib/index.py,sha256=lTbw268rRhj8dw1sib3VZ_0EhSGgoJO3FKJzSFMOaeA,20797
pip/_vendor/distlib/locators.py,sha256=oBeAZpFuPQSY09MgNnLfQGGAXXvVO96BFpZyKMuK4tM,51026
pip/_vendor/distlib/manifest.py,sha256=3qfmAmVwxRqU1o23AlfXrQGZzh6g_GGzTAP_Hb9C5zQ,14168
pip/_vendor/distlib/markers.py,sha256=X6sDvkFGcYS8gUW8hfsWuKEKAqhQZAJ7iXOMLxRYjYk,5164
pip/_vendor/distlib/metadata.py,sha256=zil3sg2EUfLXVigljY2d_03IJt-JSs7nX-73fECMX2s,38724
pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820
pip/_vendor/distlib/scripts.py,sha256=BJliaDAZaVB7WAkwokgC3HXwLD2iWiHaVI50H7C6eG8,18608
pip/_vendor/distlib/t32.exe,sha256=a0GV5kCoWsMutvliiCKmIgV98eRZ33wXoS-XrqvJQVs,97792
pip/_vendor/distlib/t64-arm.exe,sha256=68TAa32V504xVBnufojh0PcenpR3U4wAqTqf-MZqbPw,182784
pip/_vendor/distlib/t64.exe,sha256=gaYY8hy4fbkHYTTnA4i26ct8IQZzkBG2pRdy0iyuBrc,108032
pip/_vendor/distlib/util.py,sha256=vMPGvsS4j9hF6Y9k3Tyom1aaHLb0rFmZAEyzeAdel9w,66682
pip/_vendor/distlib/version.py,sha256=s5VIs8wBn0fxzGxWM_aA2ZZyx525HcZbMvcTlTyZ3Rg,23727
pip/_vendor/distlib/w32.exe,sha256=R4csx3-OGM9kL4aPIzQKRo5TfmRSHZo6QWyLhDhNBks,91648
pip/_vendor/distlib/w64-arm.exe,sha256=xdyYhKj0WDcVUOCb05blQYvzdYIKMbmJn2SZvzkcey4,168448
pip/_vendor/distlib/w64.exe,sha256=ejGf-rojoBfXseGLpya6bFTFPWRG21X5KvU8J5iU-K0,101888
pip/_vendor/distlib/wheel.py,sha256=DFIVguEQHCdxnSdAO0dfFsgMcvVZitg7bCOuLwZ7A_s,43979
pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
pip/_vendor/distro/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/distro/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/distro/__pycache__/distro.cpython-310.pyc,,
pip/_vendor/distro/distro.py,sha256=XqbefacAhDT4zr_trnbA15eY8vdK4GTghgmvUGrEM_4,49430
pip/_vendor/distro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868
pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/codec.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/core.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc,,
pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc,,
pip/_vendor/idna/codec.py,sha256=PEew3ItwzjW4hymbasnty2N2OXvNcgHB-JjrBuxHPYY,3422
pip/_vendor/idna/compat.py,sha256=RzLy6QQCdl9784aFhb2EX9EKGCJjg0P3PilGdeXXcx8,316
pip/_vendor/idna/core.py,sha256=YJYyAMnwiQEPjVC4-Fqu_p4CJ6yKKuDGmppBNQNQpFs,13239
pip/_vendor/idna/idnadata.py,sha256=W30GcIGvtOWYwAjZj4ZjuouUutC6ffgNuyjJy7fZ-lo,78306
pip/_vendor/idna/intranges.py,sha256=amUtkdhYcQG8Zr-CoMM_kVRacxkivC1WgxN1b63KKdU,1898
pip/_vendor/idna/package_data.py,sha256=q59S3OXsc5VI8j6vSD0sGBMyk6zZ4vWFREE88yCJYKs,21
pip/_vendor/idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/idna/uts46data.py,sha256=rt90K9J40gUSwppDPCrhjgi5AA6pWM65dEGRSf6rIhM,239289
pip/_vendor/msgpack/__init__.py,sha256=reRaiOtEzSjPnr7TpxjgIvbfln5pV66FhricAs2eC-g,1109
pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc,,
pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc,,
pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
pip/_vendor/msgpack/ext.py,sha256=kteJv03n9tYzd5oo3xYopVTo4vRaAxonBQQJhXohZZo,5726
pip/_vendor/msgpack/fallback.py,sha256=0g1Pzp0vtmBEmJ5w9F3s_-JMVURP8RS4G1cc5TRaAsI,32390
pip/_vendor/packaging/__init__.py,sha256=dk4Ta_vmdVJxYHDcfyhvQNw8V3PgSBomKNXqg-D2JDY,494
pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_elffile.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_parser.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/_tokenizer.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/metadata.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc,,
pip/_vendor/packaging/__pycache__/version.cpython-310.pyc,,
pip/_vendor/packaging/_elffile.py,sha256=cflAQAkE25tzhYmq_aCi72QfbT_tn891tPzfpbeHOwE,3306
pip/_vendor/packaging/_manylinux.py,sha256=vl5OCoz4kx80H5rwXKeXWjl9WNISGmr4ZgTpTP9lU9c,9612
pip/_vendor/packaging/_musllinux.py,sha256=p9ZqNYiOItGee8KcZFeHF_YcdhVwGHdK6r-8lgixvGQ,2694
pip/_vendor/packaging/_parser.py,sha256=s_TvTvDNK0NrM2QB3VKThdWFM4Nc0P6JnkObkl3MjpM,10236
pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
pip/_vendor/packaging/_tokenizer.py,sha256=J6v5H7Jzvb-g81xp_2QACKwO7LxHQA6ikryMU7zXwN8,5273
pip/_vendor/packaging/licenses/__init__.py,sha256=A116-FU49_Dz4162M4y1uAiZN4Rgdc83FxNd8EjlfqI,5727
pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-310.pyc,,
pip/_vendor/packaging/licenses/_spdx.py,sha256=oAm1ztPFwlsmCKe7lAAsv_OIOfS1cWDu9bNBkeu-2ns,48398
pip/_vendor/packaging/markers.py,sha256=c89TNzB7ZdGYhkovm6PYmqGyHxXlYVaLW591PHUNKD8,10561
pip/_vendor/packaging/metadata.py,sha256=YJibM7GYe4re8-0a3OlXmGS-XDgTEoO4tlBt2q25Bng,34762
pip/_vendor/packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/packaging/requirements.py,sha256=gYyRSAdbrIyKDY66ugIDUQjRMvxkH2ALioTmX3tnL6o,2947
pip/_vendor/packaging/specifiers.py,sha256=hGU6kuCd77bL-msIL6yLCp6MNT75RSMUKZDuju26c8U,40098
pip/_vendor/packaging/tags.py,sha256=CFqrJzAzc2XNGexerH__T-Y5Iwq7WbsYXsiLERLWxY0,21014
pip/_vendor/packaging/utils.py,sha256=0F3Hh9OFuRgrhTgGZUl5K22Fv1YP2tZl1z_2gO6kJiA,5050
pip/_vendor/packaging/version.py,sha256=oiHqzTUv_p12hpjgsLDVcaF5hT7pDaSOViUNMD4GTW0,16688
pip/_vendor/pkg_resources/__init__.py,sha256=jrhDRbOubP74QuPXxd7U7Po42PH2l-LZ2XfcO7llpZ4,124463
pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/platformdirs/__init__.py,sha256=JueR2cRLkxY7iwik-qNWJCwKOrAlBgVgcZ_IHQzqGLE,22344
pip/_vendor/platformdirs/__main__.py,sha256=jBJ8zb7Mpx5ebcqF83xrpO94MaeCpNGHVf9cvDN2JLg,1505
pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc,,
pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc,,
pip/_vendor/platformdirs/android.py,sha256=kV5oL3V3DZ6WZKu9yFiQupv18yp_jlSV2ChH1TmPcds,9007
pip/_vendor/platformdirs/api.py,sha256=2dfUDNbEXeDhDKarqtR5NY7oUikUZ4RZhs3ozstmhBQ,9246
pip/_vendor/platformdirs/macos.py,sha256=UlbyFZ8Rzu3xndCqQEHrfsYTeHwYdFap1Ioz-yxveT4,6154
pip/_vendor/platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/platformdirs/unix.py,sha256=uRPJWRyQEtv7yOSvU94rUmsblo5XKDLA1SzFg55kbK0,10393
pip/_vendor/platformdirs/version.py,sha256=oH4KgTfK4AklbTYVcV_yynvJ9JLI3pyvDVay0hRsLCs,411
pip/_vendor/platformdirs/windows.py,sha256=IFpiohUBwxPtCzlyKwNtxyW4Jk8haa6W8o59mfrDXVo,10125
pip/_vendor/pygments/__init__.py,sha256=7N1oiaWulw_nCsTY4EEixYLz15pWY5u4uPAFFi-ielU,2983
pip/_vendor/pygments/__main__.py,sha256=isIhBxLg65nLlXukG4VkMuPfNdd7gFzTZ_R_z3Q8diY,353
pip/_vendor/pygments/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/cmdline.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/console.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/filter.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/formatter.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/lexer.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/modeline.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/plugin.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/regexopt.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/scanner.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/sphinxext.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/style.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/token.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/unistring.cpython-310.pyc,,
pip/_vendor/pygments/__pycache__/util.cpython-310.pyc,,
pip/_vendor/pygments/cmdline.py,sha256=LIVzmAunlk9sRJJp54O4KRy9GDIN4Wu13v9p9QzfGPM,23656
pip/_vendor/pygments/console.py,sha256=yhP9UsLAVmWKVQf2446JJewkA7AiXeeTf4Ieg3Oi2fU,1718
pip/_vendor/pygments/filter.py,sha256=_ADNPCskD8_GmodHi6_LoVgPU3Zh336aBCT5cOeTMs0,1910
pip/_vendor/pygments/filters/__init__.py,sha256=RdedK2KWKXlKwR7cvkfr3NUj9YiZQgMgilRMFUg2jPA,40392
pip/_vendor/pygments/filters/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/formatter.py,sha256=jDWBTndlBH2Z5IYZFVDnP0qn1CaTQjTWt7iAGtCnJEg,4390
pip/_vendor/pygments/formatters/__init__.py,sha256=8No-NUs8rBTSSBJIv4hSEQt2M0cFB4hwAT0snVc2QGE,5385
pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/groff.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/html.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/img.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/irc.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/latex.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/other.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/svg.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-310.pyc,,
pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-310.pyc,,
pip/_vendor/pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176
pip/_vendor/pygments/formatters/bbcode.py,sha256=3JQLI45tcrQ_kRUMjuab6C7Hb0XUsbVWqqbSn9cMjkI,3320
pip/_vendor/pygments/formatters/groff.py,sha256=M39k0PaSSZRnxWjqBSVPkF0mu1-Vr7bm6RsFvs-CNN4,5106
pip/_vendor/pygments/formatters/html.py,sha256=SE2jc3YCqbMS3rZW9EAmDlAUhdVxJ52gA4dileEvCGU,35669
pip/_vendor/pygments/formatters/img.py,sha256=MwA4xWPLOwh6j7Yc6oHzjuqSPt0M1fh5r-5BTIIUfsU,23287
pip/_vendor/pygments/formatters/irc.py,sha256=dp1Z0l_ObJ5NFh9MhqLGg5ptG5hgJqedT2Vkutt9v0M,4981
pip/_vendor/pygments/formatters/latex.py,sha256=XMmhOCqUKDBQtG5mGJNAFYxApqaC5puo5cMmPfK3944,19306
pip/_vendor/pygments/formatters/other.py,sha256=56PMJOliin-rAUdnRM0i1wsV1GdUPd_dvQq0_UPfF9c,5034
pip/_vendor/pygments/formatters/pangomarkup.py,sha256=y16U00aVYYEFpeCfGXlYBSMacG425CbfoG8oKbKegIg,2218
pip/_vendor/pygments/formatters/rtf.py,sha256=ZT90dmcKyJboIB0mArhL7IhE467GXRN0G7QAUgG03To,11957
pip/_vendor/pygments/formatters/svg.py,sha256=KKsiophPupHuxm0So-MsbQEWOT54IAiSF7hZPmxtKXE,7174
pip/_vendor/pygments/formatters/terminal.py,sha256=AojNG4MlKq2L6IsC_VnXHu4AbHCBn9Otog6u45XvxeI,4674
pip/_vendor/pygments/formatters/terminal256.py,sha256=kGkNUVo3FpwjytIDS0if79EuUoroAprcWt3igrcIqT0,11753
pip/_vendor/pygments/lexer.py,sha256=TYHDt___gNW4axTl2zvPZff-VQi8fPaIh5OKRcVSjUM,35349
pip/_vendor/pygments/lexers/__init__.py,sha256=pIlxyQJuu_syh9lE080cq8ceVbEVcKp0osAFU5fawJU,12115
pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-310.pyc,,
pip/_vendor/pygments/lexers/__pycache__/python.cpython-310.pyc,,
pip/_vendor/pygments/lexers/_mapping.py,sha256=61-h3zr103m01OS5BUq_AfUiL9YI06Ves9ipQ7k4vr4,76097
pip/_vendor/pygments/lexers/python.py,sha256=2J_YJrPTr_A6fJY_qKiKv0GpgPwHMrlMSeo59qN3fe4,53687
pip/_vendor/pygments/modeline.py,sha256=gtRYZBS-CKOCDXHhGZqApboHBaZwGH8gznN3O6nuxj4,1005
pip/_vendor/pygments/plugin.py,sha256=ioeJ3QeoJ-UQhZpY9JL7vbxsTVuwwM7BCu-Jb8nN0AU,1891
pip/_vendor/pygments/regexopt.py,sha256=Hky4EB13rIXEHQUNkwmCrYqtIlnXDehNR3MztafZ43w,3072
pip/_vendor/pygments/scanner.py,sha256=NDy3ofK_fHRFK4hIDvxpamG871aewqcsIb6sgTi7Fhk,3092
pip/_vendor/pygments/sphinxext.py,sha256=iOptJBcqOGPwMEJ2p70PvwpZPIGdvdZ8dxvq6kzxDgA,7981
pip/_vendor/pygments/style.py,sha256=rSCZWFpg1_DwFMXDU0nEVmAcBHpuQGf9RxvOPPQvKLQ,6420
pip/_vendor/pygments/styles/__init__.py,sha256=qUk6_1z5KmT8EdJFZYgESmG6P_HJF_2vVrDD7HSCGYY,2042
pip/_vendor/pygments/styles/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pygments/styles/__pycache__/_mapping.cpython-310.pyc,,
pip/_vendor/pygments/styles/_mapping.py,sha256=6lovFUE29tz6EsV3XYY4hgozJ7q1JL7cfO3UOlgnS8w,3312
pip/_vendor/pygments/token.py,sha256=qZwT7LSPy5YBY3JgDjut642CCy7JdQzAfmqD9NmT5j0,6226
pip/_vendor/pygments/unistring.py,sha256=p5c1i-HhoIhWemy9CUsaN9o39oomYHNxXll0Xfw6tEA,63208
pip/_vendor/pygments/util.py,sha256=2tj2nS1X9_OpcuSjf8dOET2bDVZhs8cEKd_uT6-Fgg8,10031
pip/_vendor/pyproject_hooks/__init__.py,sha256=cPB_a9LXz5xvsRbX1o2qyAdjLatZJdQ_Lc5McNX-X7Y,691
pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-310.pyc,,
pip/_vendor/pyproject_hooks/_impl.py,sha256=jY-raxnmyRyB57ruAitrJRUzEexuAhGTpgMygqx67Z4,14936
pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=MJNPpfIxcO-FghxpBbxkG1rFiQf6HOUbV4U5mq0HFns,557
pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-310.pyc,,
pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=qcXMhmx__MIJq10gGHW3mA4Tl8dy8YzHMccwnNoKlw0,12216
pip/_vendor/pyproject_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/requests/__init__.py,sha256=HlB_HzhrzGtfD_aaYUwUh1zWXLZ75_YCLyit75d0Vz8,5057
pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/api.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/auth.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/certs.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/compat.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/help.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/models.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/packages.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/structures.cpython-310.pyc,,
pip/_vendor/requests/__pycache__/utils.cpython-310.pyc,,
pip/_vendor/requests/__version__.py,sha256=FVfglgZmNQnmYPXpOohDU58F5EUb_-VnSTaAesS187g,435
pip/_vendor/requests/_internal_utils.py,sha256=nMQymr4hs32TqVo5AbCrmcJEhvPUh7xXlluyqwslLiQ,1495
pip/_vendor/requests/adapters.py,sha256=J7VeVxKBvawbtlX2DERVo05J9BXTcWYLMHNd1Baa-bk,27607
pip/_vendor/requests/api.py,sha256=_Zb9Oa7tzVIizTKwFrPjDEY9ejtm_OnSRERnADxGsQs,6449
pip/_vendor/requests/auth.py,sha256=kF75tqnLctZ9Mf_hm9TZIj4cQWnN5uxRz8oWsx5wmR0,10186
pip/_vendor/requests/certs.py,sha256=kHDlkK_beuHXeMPc5jta2wgl8gdKeUWt5f2nTDVrvt8,441
pip/_vendor/requests/compat.py,sha256=Mo9f9xZpefod8Zm-n9_StJcVTmwSukXR2p3IQyyVXvU,1485
pip/_vendor/requests/cookies.py,sha256=bNi-iqEj4NPZ00-ob-rHvzkvObzN3lEpgw3g6paS3Xw,18590
pip/_vendor/requests/exceptions.py,sha256=D1wqzYWne1mS2rU43tP9CeN1G7QAy7eqL9o1god6Ejw,4272
pip/_vendor/requests/help.py,sha256=hRKaf9u0G7fdwrqMHtF3oG16RKktRf6KiwtSq2Fo1_0,3813
pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
pip/_vendor/requests/models.py,sha256=x4K4CmH-lC0l2Kb-iPfMN4dRXxHEcbOaEWBL_i09AwI,35483
pip/_vendor/requests/packages.py,sha256=_ZQDCJTJ8SP3kVWunSqBsRZNPzj2c1WFVqbdr08pz3U,1057
pip/_vendor/requests/sessions.py,sha256=ykTI8UWGSltOfH07HKollH7kTBGw4WhiBVaQGmckTw4,30495
pip/_vendor/requests/status_codes.py,sha256=iJUAeA25baTdw-6PfD0eF4qhpINDJRJI-yaMqxs4LEI,4322
pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
pip/_vendor/requests/utils.py,sha256=L79vnFbzJ3SFLKtJwpoWe41Tozi3RlZv94pY1TFIyow,33631
pip/_vendor/resolvelib/__init__.py,sha256=h509TdEcpb5-44JonaU3ex2TM15GVBLjM9CNCPwnTTs,537
pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc,,
pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc,,
pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc,,
pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156
pip/_vendor/resolvelib/providers.py,sha256=fuuvVrCetu5gsxPB43ERyjfO8aReS3rFQHpDgiItbs4,5871
pip/_vendor/resolvelib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/resolvelib/reporters.py,sha256=TSbRmWzTc26w0ggsV1bxVpeWDB8QNIre6twYl7GIZBE,1601
pip/_vendor/resolvelib/resolvers.py,sha256=G8rsLZSq64g5VmIq-lB7UcIJ1gjAxIQJmTF4REZleQ0,20511
pip/_vendor/resolvelib/structs.py,sha256=0_1_XO8z_CLhegP3Vpf9VJ3zJcfLm0NOHRM-i0Ykz3o,4963
pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090
pip/_vendor/rich/__main__.py,sha256=eO7Cq8JnrgG8zVoeImiAs92q3hXNMIfp0w5lMsO7Q2Y,8477
pip/_vendor/rich/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/__main__.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_cell_widths.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_emoji_codes.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_emoji_replace.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_export_format.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_extension.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_fileno.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_inspect.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_log_render.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_loop.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_null_file.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_palettes.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_pick.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_ratio.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_spinners.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_stack.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_timer.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_win32_console.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_windows.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_windows_renderer.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/_wrap.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/abc.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/align.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/ansi.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/bar.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/box.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/cells.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/color.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/color_triplet.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/columns.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/console.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/constrain.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/containers.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/control.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/default_styles.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/diagnose.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/emoji.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/errors.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/file_proxy.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/filesize.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/highlighter.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/json.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/jupyter.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/layout.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/live.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/live_render.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/logging.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/markup.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/measure.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/padding.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/pager.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/palette.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/panel.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/pretty.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/progress.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/progress_bar.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/prompt.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/protocol.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/region.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/repr.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/rule.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/scope.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/screen.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/segment.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/spinner.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/status.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/style.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/styled.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/syntax.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/table.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/terminal_theme.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/text.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/theme.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/themes.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/traceback.cpython-310.pyc,,
pip/_vendor/rich/__pycache__/tree.cpython-310.pyc,,
pip/_vendor/rich/_cell_widths.py,sha256=fbmeyetEdHjzE_Vx2l1uK7tnPOhMs2X1lJfO3vsKDpA,10209
pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
pip/_vendor/rich/_export_format.py,sha256=RI08pSrm5tBSzPMvnbTqbD9WIalaOoN5d4M1RTmLq1Y,2128
pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
pip/_vendor/rich/_fileno.py,sha256=HWZxP5C2ajMbHryvAQZseflVfQoGzsKOHzKGsLD8ynQ,799
pip/_vendor/rich/_inspect.py,sha256=QM05lEFnFoTaFqpnbx-zBEI6k8oIKrD3cvjEOQNhKig,9655
pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
pip/_vendor/rich/_null_file.py,sha256=ADGKp1yt-k70FMKV6tnqCqecB-rSJzp-WQsD7LPL-kg,1394
pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
pip/_vendor/rich/_ratio.py,sha256=Zt58apszI6hAAcXPpgdWKpu3c31UBWebOeR4mbyptvU,5471
pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
pip/_vendor/rich/_win32_console.py,sha256=BSaDRIMwBLITn_m0mTRLPqME5q-quGdSMuYMpYeYJwc,22755
pip/_vendor/rich/_windows.py,sha256=aBwaD_S56SbgopIvayVmpk0Y28uwY2C5Bab1wl3Bp-I,1925
pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
pip/_vendor/rich/_wrap.py,sha256=FlSsom5EX0LVkA3KWy34yHnCfLtqX-ZIepXKh-70rpc,3404
pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
pip/_vendor/rich/align.py,sha256=Rh-3adnDaN1Ao07EjR2PhgE62PGLPgO8SMwJBku1urQ,10469
pip/_vendor/rich/ansi.py,sha256=Avs1LHbSdcyOvDOdpELZUoULcBiYewY76eNBp6uFBhs,6921
pip/_vendor/rich/bar.py,sha256=ldbVHOzKJOnflVNuv1xS7g6dLX2E3wMnXkdPbpzJTcs,3263
pip/_vendor/rich/box.py,sha256=nr5fYIUghB_iUCEq6y0Z3LlCT8gFPDrzN9u2kn7tJl4,10831
pip/_vendor/rich/cells.py,sha256=KrQkj5-LghCCpJLSNQIyAZjndc4bnEqOEmi5YuZ9UCY,5130
pip/_vendor/rich/color.py,sha256=3HSULVDj7qQkXUdFWv78JOiSZzfy5y1nkcYhna296V0,18211
pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
pip/_vendor/rich/console.py,sha256=nKjrEx_7xy8KGmDVT-BgNII0R5hm1cexhAHDwdwNVqg,100156
pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
pip/_vendor/rich/containers.py,sha256=c_56TxcedGYqDepHBMTuZdUIijitAQgnox-Qde0Z1qo,5502
pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630
pip/_vendor/rich/default_styles.py,sha256=dZxgaSD9VUy7SXQShO33aLYiAWspCr2sCQZFX_JK1j4,8159
pip/_vendor/rich/diagnose.py,sha256=an6uouwhKPAlvQhYpNNpGq9EJysfMIOvvCbO3oSoR24,972
pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501
pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
pip/_vendor/rich/file_proxy.py,sha256=Tl9THMDZ-Pk5Wm8sI1gGg_U5DhusmxD-FZ0fUbcU0W0,1683
pip/_vendor/rich/filesize.py,sha256=_iz9lIpRgvW7MNSeCZnLg-HwzbP4GETg543WqD8SFs0,2484
pip/_vendor/rich/highlighter.py,sha256=G_sn-8DKjM1sEjLG_oc4ovkWmiUpWvj8bXi0yed2LnY,9586
pip/_vendor/rich/json.py,sha256=vVEoKdawoJRjAFayPwXkMBPLy7RSTs-f44wSQDR2nJ0,5031
pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
pip/_vendor/rich/layout.py,sha256=ajkSFAtEVv9EFTcFs-w4uZfft7nEXhNzL7ZVdgrT5rI,14004
pip/_vendor/rich/live.py,sha256=DhzAPEnjTxQuq9_0Y2xh2MUwQcP_aGPkenLfKETslwM,14270
pip/_vendor/rich/live_render.py,sha256=zJtB471jGziBtEwxc54x12wEQtH4BuQr1SA8v9kU82w,3666
pip/_vendor/rich/logging.py,sha256=ZgpKMMBY_BuMAI_BYzo-UtXak6t5oH9VK8m9Q2Lm0f4,12458
pip/_vendor/rich/markup.py,sha256=3euGKP5s41NCQwaSjTnJxus5iZMHjxpIM0W6fCxra38,8451
pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
pip/_vendor/rich/padding.py,sha256=KVEI3tOwo9sgK1YNSuH__M1_jUWmLZwRVV_KmOtVzyM,4908
pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
pip/_vendor/rich/panel.py,sha256=fFRHcviXvWhk3V3zx5Zwmsb_RL9KJ3esD-sU0NYEVyw,11235
pip/_vendor/rich/pretty.py,sha256=gy3S72u4FRg2ytoo7N1ZDWDIvB4unbzd5iUGdgm-8fc,36391
pip/_vendor/rich/progress.py,sha256=MtmCjTk5zYU_XtRHxRHTAEHG6hF9PeF7EMWbEPleIC0,60357
pip/_vendor/rich/progress_bar.py,sha256=mZTPpJUwcfcdgQCTTz3kyY-fc79ddLwtx6Ghhxfo064,8162
pip/_vendor/rich/prompt.py,sha256=l0RhQU-0UVTV9e08xW1BbIj0Jq2IXyChX4lC0lFNzt4,12447
pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
pip/_vendor/rich/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
pip/_vendor/rich/repr.py,sha256=5MZJZmONgC6kud-QW-_m1okXwL2aR6u6y-pUcUCJz28,4431
pip/_vendor/rich/rule.py,sha256=0fNaS_aERa3UMRc3T5WMpN_sumtDxfaor2y3of1ftBk,4602
pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843
pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
pip/_vendor/rich/segment.py,sha256=otnKeKGEV-WRlQVosfJVeFDcDxAKHpvJ_hLzSu5lumM,24743
pip/_vendor/rich/spinner.py,sha256=PT5qgXPG3ZpqRj7n3EZQ6NW56mx3ldZqZCU7gEMyZk4,4364
pip/_vendor/rich/status.py,sha256=kkPph3YeAZBo-X-4wPp8gTqZyU466NLwZBA4PZTTewo,4424
pip/_vendor/rich/style.py,sha256=aSoUNbVgfP1PAnduAqgbbl4AMQy668qs2S1FEwr3Oqs,27067
pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
pip/_vendor/rich/syntax.py,sha256=qqAnEUZ4K57Po81_5RBxnsuU4KRzSdvDPAhKw8ma_3E,35763
pip/_vendor/rich/table.py,sha256=yXYUr0YsPpG466N50HCAw2bpb5ZUuuzdc-G66Zk-oTc,40103
pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
pip/_vendor/rich/text.py,sha256=AO7JPCz6-gaN1thVLXMBntEmDPVYFgFNG1oM61_sanU,47552
pip/_vendor/rich/theme.py,sha256=oNyhXhGagtDlbDye3tVu3esWOWk0vNkuxFw-_unlaK0,3771
pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
pip/_vendor/rich/traceback.py,sha256=z8UoN7NbTQKW6YDDUVwOh7F8snZf6gYnUWtOrKsLE1w,31797
pip/_vendor/rich/tree.py,sha256=yWnQ6rAvRGJ3qZGqBrxS2SW2TKBTNrP0SdY8QxOFPuw,9451
pip/_vendor/tomli/__init__.py,sha256=PhNw_eyLgdn7McJ6nrAN8yIm3dXC75vr1sVGVVwDSpA,314
pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc,,
pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc,,
pip/_vendor/tomli/__pycache__/_types.cpython-310.pyc,,
pip/_vendor/tomli/_parser.py,sha256=9w8LG0jB7fwmZZWB0vVXbeejDHcl4ANIJxB2scEnDlA,25591
pip/_vendor/tomli/_re.py,sha256=sh4sBDRgO94KJZwNIrgdcyV_qQast50YvzOAUGpRDKA,3171
pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
pip/_vendor/tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
pip/_vendor/truststore/__init__.py,sha256=WIDeyzWm7EVX44g354M25vpRXbeY1lsPH6EmUJUcq4o,1264
pip/_vendor/truststore/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/truststore/__pycache__/_api.cpython-310.pyc,,
pip/_vendor/truststore/__pycache__/_macos.cpython-310.pyc,,
pip/_vendor/truststore/__pycache__/_openssl.cpython-310.pyc,,
pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-310.pyc,,
pip/_vendor/truststore/__pycache__/_windows.cpython-310.pyc,,
pip/_vendor/truststore/_api.py,sha256=GeXRNTlxPZ3kif4kNoh6JY0oE4QRzTGcgXr6l_X_Gk0,10555
pip/_vendor/truststore/_macos.py,sha256=nZlLkOmszUE0g6ryRwBVGY5COzPyudcsiJtDWarM5LQ,20503
pip/_vendor/truststore/_openssl.py,sha256=LLUZ7ZGaio-i5dpKKjKCSeSufmn6T8pi9lDcFnvSyq0,2324
pip/_vendor/truststore/_ssl_constants.py,sha256=NUD4fVKdSD02ri7-db0tnO0VqLP9aHuzmStcW7tAl08,1130
pip/_vendor/truststore/_windows.py,sha256=rAHyKYD8M7t-bXfG8VgOVa3TpfhVhbt4rZQlO45YuP8,17993
pip/_vendor/truststore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/typing_extensions.py,sha256=78hFl0HpDY-ylHUVCnWdU5nTHxUP2-S-3wEZk6CQmLk,134499
pip/_vendor/urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333
pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc,,
pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc,,
pip/_vendor/urllib3/_collections.py,sha256=pyASJJhW7wdOpqJj9QJA8FyGRfr8E8uUUhqUvhF0728,11372
pip/_vendor/urllib3/_version.py,sha256=t9wGB6ooOTXXgiY66K1m6BZS1CJyXHAU8EoWDTe6Shk,64
pip/_vendor/urllib3/connection.py,sha256=ttIA909BrbTUzwkqEe_TzZVh4JOOj7g61Ysei2mrwGg,20314
pip/_vendor/urllib3/connectionpool.py,sha256=e2eiAwNbFNCKxj4bwDKNK-w7HIdSz3OmMxU_TIt-evQ,40408
pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc,,
pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
pip/_vendor/urllib3/contrib/appengine.py,sha256=VR68eAVE137lxTgjBDwCna5UiBZTOKa01Aj_-5BaCz4,11036
pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528
pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=hDJh4MhyY_p-oKlFcYcQaVQRDv6GMmBGuW9yjxyeejM,17081
pip/_vendor/urllib3/contrib/securetransport.py,sha256=Fef1IIUUFHqpevzXiDPbIGkDKchY2FVKeVeLGR1Qq3g,34446
pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-310.pyc,,
pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
pip/_vendor/urllib3/packages/backports/weakref_finalize.py,sha256=tRCal5OAhNSRyb0DhHp-38AtIlCsRP8BxF3NX-6rqIA,5343
pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
pip/_vendor/urllib3/poolmanager.py,sha256=aWyhXRtNO4JUnCSVVqKTKQd8EXTvUm1VN9pgs2bcONo,19990
pip/_vendor/urllib3/request.py,sha256=YTWFNr7QIwh7E1W9dde9LM77v2VWTJ5V78XuTTw7D1A,6691
pip/_vendor/urllib3/response.py,sha256=fmDJAFkG71uFTn-sVSTh2Iw0WmcXQYqkbRjihvwBjU8,30641
pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc,,
pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc,,
pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997
pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
pip/_vendor/urllib3/util/retry.py,sha256=6ENvOZ8PBDzh8kgixpql9lIrb2dxH-k7ZmBanJF2Ng4,22050
pip/_vendor/urllib3/util/ssl_.py,sha256=QDuuTxPSCj1rYtZ4xpD7Ux-r20TD50aHyqKyhQ7Bq4A,17460
pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
pip/_vendor/urllib3/util/timeout.py,sha256=cwq4dMk87mJHSBktK1miYJ-85G-3T3RmT20v7SFCpno,10168
pip/_vendor/urllib3/util/url.py,sha256=lCAE7M5myA8EDdW0sJuyyZhVB9K_j38ljWhHAnFaWoE,14296
pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
pip/_vendor/vendor.txt,sha256=EW-E3cE5XEAtVFzGInikArOMDxGP0DLUWzXpY4RZfFY,333
pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
@@ -1,5 +1,5 @@
Wheel-Version: 1.0 Wheel-Version: 1.0
Generator: bdist_wheel (0.37.1) Generator: setuptools (75.8.0)
Root-Is-Purelib: true Root-Is-Purelib: true
Tag: py3-none-any Tag: py3-none-any
@@ -1,4 +1,3 @@
[console_scripts] [console_scripts]
pip = pip._internal.cli.main:main pip = pip._internal.cli.main:main
pip3 = pip._internal.cli.main:main pip3 = pip._internal.cli.main:main
pip3.8 = pip._internal.cli.main:main
Loaded 100 of 1164 files, more files were not shown because too many files have changed in this diff. Show more