This commit is contained in:
dingfeng.wong
2025-07-22 01:51:19 +08:00
parent eb47b6a22d
commit e0e5edbfdc
5 changed files with 688 additions and 28 deletions
+145 -15
View File
@@ -5,40 +5,170 @@ A collection of useful command-line tools.
## OCR Screenshot Tool ## OCR Screenshot Tool
A CLI tool that takes region screenshots on macOS, performs OCR using Tesseract, and copies the result to clipboard. A cross-platform CLI tool that takes screenshots, performs OCR using DocTR (state-of-the-art deep learning OCR), and copies the result to clipboard. Features intelligent text formatting preservation and optional image annotation.
### Prerequisites ### Features
- macOS (uses built-in `screencapture` command) - 🌍 **Cross-platform** - Works on Windows, macOS, and Linux
- Tesseract OCR (install with `brew install tesseract`) - **Multiple screenshot methods** - Choose the fastest for your system
- 🔍 **Advanced OCR** - Uses DocTR with PARSeq recognition model
- 📝 **Smart formatting** - Preserves text layout and indentation
- 🎨 **Image annotation** - Visualize detected text regions
- 📋 **Clipboard integration** - Automatic text copying
### Installation
#### Basic installation:
```bash
pip install .
```
#### With cross-platform screenshot support:
```bash
# For fastest screenshots (recommended)
pip install ".[screenshot-fast]"
# For full automation features (region selection)
pip install ".[screenshot-full]"
# For maximum compatibility (all backends)
pip install ".[screenshot-all]"
```
#### Install specific screenshot libraries:
```bash
pip install mss # Fastest (~30x faster than others)
pip install pyautogui # Interactive region selection
pip install pyscreenshot # Multiple backends
```
### Usage ### Usage
Basic usage (takes screenshot, performs OCR, copies to clipboard): #### Basic Commands
Take a screenshot and perform OCR:
```bash ```bash
uv run ocr-screenshot ocr-screenshot
``` ```
With verbose output: With verbose output and annotation:
```bash ```bash
uv run ocr-screenshot --verbose ocr-screenshot --verbose --annotate --save-image
``` ```
Save the screenshot image: #### Screenshot Methods
Choose your preferred screenshot method:
```bash ```bash
uv run ocr-screenshot --save-image # Auto-detect best method (default)
ocr-screenshot --screenshot-method auto
# Use MSS (fastest)
ocr-screenshot --screenshot-method mss
# Use PyAutoGUI (supports region selection)
ocr-screenshot --screenshot-method pyautogui
# Use Pillow ImageGrab (built-in)
ocr-screenshot --screenshot-method pillow
# Interactive region selection
ocr-screenshot --screenshot-method interactive
# macOS native (region selection with drag)
ocr-screenshot --screenshot-method macos
``` ```
Specify OCR language (e.g., for Chinese): #### Advanced Features
Save screenshot with annotation showing detected text:
```bash ```bash
uv run ocr-screenshot --lang chi_sim ocr-screenshot --save-image --annotate --show-words --show-text
``` ```
Capture specific monitor (MSS method):
```bash
ocr-screenshot --screenshot-method mss --monitor-number 2
```
Full annotation with all detection levels:
```bash
ocr-screenshot --annotate --show-words --show-lines --show-blocks --show-text --save-image
```
### Screenshot Method Comparison
| Method | Speed | Region Selection | Cross-Platform | Notes |
|--------|-------|------------------|----------------|-------|
| **mss** | ⚡⚡⚡ Fastest | ❌ (crop after) | ✅ | ~30x faster, recommended |
| **pyautogui** | ⚡ Slow | ✅ Interactive | ✅ | Best for region selection |
| **pillow** | ⚡ Slow | ✅ Coordinates | ✅ | Built into Pillow |
| **pyscreenshot** | ⚡ Variable | ✅ Coordinates | ✅ | Multiple backends |
| **macos** | ⚡⚡ Fast | ✅ Native UI | 🍎 macOS only | Native drag selection |
### How it works ### How it works
1. **Screenshot**: Click and drag to select a region, or press Space to capture an entire window 1. **Screenshot**: Multiple cross-platform methods available
2. **OCR**: The selected region is processed with Tesseract OCR - **Auto**: Tries best method for your platform
3. **Clipboard**: The extracted text is automatically copied to your clipboard - **MSS**: Fastest full-screen capture
- **Interactive**: Guided region selection
- **macOS**: Native drag-to-select interface
2. **OCR**: Advanced DocTR processing
- Uses state-of-the-art PARSeq recognition model
- Preserves text layout and indentation
- Handles multiple languages
3. **Annotation** (optional): Visual feedback
- Word-level bounding boxes (red)
- Line-level groupings (green)
- Block-level sections (blue)
- Text overlay showing detected content
4. **Output**: Formatted text copied to clipboard
### Command Line Options
```bash
ocr-screenshot [OPTIONS]
Options:
--lang TEXT Language code for OCR (default: eng)
--save-image Save the screenshot image
--output-dir PATH Directory to save images (default: ~/Desktop)
--verbose Show detailed output
--annotate Create annotated image with detection boxes
--show-words Show word-level boxes (default: True)
--show-lines Show line-level boxes
--show-blocks Show block-level boxes
--show-text Overlay detected text on image
--screenshot-method TEXT Method: auto, mss, pyautogui, pillow, pyscreenshot, macos, interactive
--monitor-number INTEGER Monitor to capture (MSS method only, 0=all)
--help Show this message and exit
```
### Examples
**Quick OCR with fastest method:**
```bash
ocr-screenshot --screenshot-method mss
```
**Debug OCR accuracy with annotations:**
```bash
ocr-screenshot --annotate --show-words --show-text --save-image --verbose
```
**Interactive region selection:**
```bash
ocr-screenshot --screenshot-method interactive --save-image
```
**Multi-monitor setup (capture monitor 2):**
```bash
ocr-screenshot --screenshot-method mss --monitor-number 2
```
## Development Guide ## Development Guide
+11
View File
@@ -15,6 +15,17 @@ dependencies = [
"rich>=13.0.0", "rich>=13.0.0",
] ]
[project.optional-dependencies]
# Cross-platform screenshot libraries
screenshot-fast = ["mss>=7.0.0"] # Fastest screenshot library
screenshot-full = ["pyautogui>=0.9.54"] # Full automation including region selection
screenshot-multi = ["pyscreenshot>=3.1"] # Multiple backend support
screenshot-all = [
"mss>=7.0.0",
"pyautogui>=0.9.54",
"pyscreenshot>=3.1"
] # All screenshot libraries for maximum compatibility
[project.scripts] [project.scripts]
ocr-screenshot = "tooling.cli:cli_main" ocr-screenshot = "tooling.cli:cli_main"
+43 -13
View File
@@ -18,7 +18,7 @@ from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.syntax import Syntax from rich.syntax import Syntax
from .ocr_screenshot import copy_to_clipboard, perform_ocr, take_region_screenshot, perform_ocr_with_annotation from .ocr_screenshot import copy_to_clipboard, perform_ocr, take_region_screenshot, perform_ocr_with_annotation, take_region_screenshot_cross_platform
app = typer.Typer( app = typer.Typer(
name="ocr-screenshot", name="ocr-screenshot",
@@ -66,6 +66,14 @@ def main(
show_text: bool = typer.Option( show_text: bool = typer.Option(
default=False, default=False,
help="Overlay detected text on the annotated image" help="Overlay detected text on the annotated image"
),
screenshot_method: str = typer.Option(
default="auto",
help="Screenshot method to use: auto, mss, pyautogui, pillow, pyscreenshot, macos, interactive"
),
monitor_number: int = typer.Option(
default=0,
help="Monitor number to capture (0=all monitors, 1+=specific monitor, only for MSS method)"
) )
): ):
"""Take a region screenshot, perform OCR, and copy result to clipboard.""" """Take a region screenshot, perform OCR, and copy result to clipboard."""
@@ -83,20 +91,42 @@ def main(
try: try:
# Step 1: Take screenshot # Step 1: Take screenshot
if verbose: if verbose:
console.print("\n[bold blue]📸 Taking region screenshot...[/bold blue]") console.print(f"\n[bold blue]📸 Taking screenshot using method: {screenshot_method}[/bold blue]")
console.print(Panel(
"[bold]Instructions:[/bold]\n" # Show method-specific instructions
"• Drag to select a region\n" if screenshot_method == "macos":
"• Press [bold]Space[/bold] to capture entire window\n" console.print(Panel(
"• Press [bold]Escape[/bold] to cancel", "[bold]macOS Screenshot Instructions:[/bold]\n"
title="Screenshot Controls", "• Drag to select a region\n"
border_style="blue" "• Press [bold]Space[/bold] to capture entire window\n"
)) "• Press [bold]Escape[/bold] to cancel",
title="Screenshot Controls",
border_style="blue"
))
elif screenshot_method == "interactive":
console.print(Panel(
"[bold]Interactive Screenshot Instructions:[/bold]\n"
"• Follow the prompts to select region corners\n"
"• Position mouse and press ENTER at each corner",
title="Screenshot Controls",
border_style="green"
))
elif screenshot_method in ["mss", "pillow", "pyautogui", "pyscreenshot"]:
console.print(Panel(
f"[bold]{screenshot_method.upper()} Screenshot:[/bold]\n"
"• Full screen capture (region selection not supported in CLI yet)\n"
"• Use --screenshot-method interactive for region selection",
title="Screenshot Info",
border_style="yellow"
))
else: else:
console.print("[bold blue]📸 Taking screenshot...[/bold blue]") console.print(f"[bold blue]📸 Taking screenshot ({screenshot_method})...[/bold blue]")
if not take_region_screenshot(str(screenshot_path)): if not take_region_screenshot_cross_platform(str(screenshot_path), method=screenshot_method, monitor_number=monitor_number):
console.print("[bold red]❌ Screenshot cancelled or failed.[/bold red]") console.print(f"[bold red]❌ Screenshot failed with method '{screenshot_method}'.[/bold red]")
if screenshot_method == "auto":
console.print("[yellow]💡 Try installing additional screenshot libraries:[/yellow]")
console.print(" pip install mss pyautogui pyscreenshot")
raise typer.Exit(1) raise typer.Exit(1)
if verbose: if verbose:
+288
View File
@@ -7,6 +7,7 @@ Core functionality for taking screenshots, performing OCR using DocTR, and clipb
import os import os
import subprocess import subprocess
import sys
from typing import Optional, Tuple from typing import Optional, Tuple
import pyperclip import pyperclip
@@ -15,6 +16,293 @@ from doctr.io import DocumentFile
from doctr.models import ocr_predictor from doctr.models import ocr_predictor
def take_region_screenshot_mss(output_path: str, monitor_number: int = 0) -> bool:
"""
Take a screenshot using MSS (fastest cross-platform option).
Args:
output_path: Path where the screenshot will be saved
monitor_number: Monitor to capture (0 = all monitors, 1+ = specific monitor)
Returns:
True if screenshot was taken successfully, False otherwise
"""
try:
import mss
with mss.mss() as sct:
if monitor_number == 0:
# Capture all monitors
monitor = sct.monitors[0] # All monitors combined
else:
# Capture specific monitor
if monitor_number > len(sct.monitors) - 1:
monitor_number = 1 # Default to first monitor
monitor = sct.monitors[monitor_number]
# Capture the screen
screenshot = sct.grab(monitor)
# Convert to PIL Image and save
img = Image.frombytes("RGB", screenshot.size, screenshot.bgra, "raw", "BGRX")
img.save(output_path)
return os.path.exists(output_path) and os.path.getsize(output_path) > 0
except ImportError:
print("MSS library not installed. Install with: pip install mss")
return False
except Exception as e:
print(f"Error taking screenshot with MSS: {e}")
return False
def take_region_screenshot_pyautogui(output_path: str, region: Optional[Tuple[int, int, int, int]] = None) -> bool:
"""
Take a screenshot using PyAutoGUI (supports region selection).
Args:
output_path: Path where the screenshot will be saved
region: Optional tuple of (left, top, width, height) to capture specific region
Returns:
True if screenshot was taken successfully, False otherwise
"""
try:
import pyautogui
# Take screenshot
if region:
screenshot = pyautogui.screenshot(region=region)
else:
screenshot = pyautogui.screenshot()
# Save the screenshot
screenshot.save(output_path)
return os.path.exists(output_path) and os.path.getsize(output_path) > 0
except ImportError:
print("PyAutoGUI library not installed. Install with: pip install pyautogui")
return False
except Exception as e:
print(f"Error taking screenshot with PyAutoGUI: {e}")
return False
def take_region_screenshot_pillow(output_path: str, bbox: Optional[Tuple[int, int, int, int]] = None) -> bool:
"""
Take a screenshot using PIL/Pillow ImageGrab (built into Pillow).
Args:
output_path: Path where the screenshot will be saved
bbox: Optional tuple of (left, top, right, bottom) to capture specific region
Returns:
True if screenshot was taken successfully, False otherwise
"""
try:
from PIL import ImageGrab
# Take screenshot
screenshot = ImageGrab.grab(bbox=bbox)
if screenshot is None:
return False
# Save the screenshot
screenshot.save(output_path)
return os.path.exists(output_path) and os.path.getsize(output_path) > 0
except Exception as e:
print(f"Error taking screenshot with Pillow: {e}")
return False
def take_region_screenshot_pyscreenshot(output_path: str, bbox: Optional[Tuple[int, int, int, int]] = None, backend: str = "auto") -> bool:
"""
Take a screenshot using pyscreenshot (multiple backends).
Args:
output_path: Path where the screenshot will be saved
bbox: Optional tuple of (left, top, right, bottom) to capture specific region
backend: Backend to use ('auto', 'mss', 'pyautogui', 'pillow', etc.)
Returns:
True if screenshot was taken successfully, False otherwise
"""
try:
import pyscreenshot as pys
# Take screenshot with specified backend
if backend != "auto":
screenshot = pys.grab(bbox=bbox, backend=backend)
else:
screenshot = pys.grab(bbox=bbox)
# Save the screenshot
screenshot.save(output_path)
return os.path.exists(output_path) and os.path.getsize(output_path) > 0
except ImportError:
print("pyscreenshot library not installed. Install with: pip install pyscreenshot")
return False
except Exception as e:
print(f"Error taking screenshot with pyscreenshot: {e}")
return False
def take_region_screenshot_interactive_pyautogui(output_path: str) -> bool:
"""
Take an interactive region screenshot using PyAutoGUI with user selection.
Args:
output_path: Path where the screenshot will be saved
Returns:
True if screenshot was taken successfully, False otherwise
"""
try:
import pyautogui
import tkinter as tk
from tkinter import messagebox
print("Click and drag to select a region...")
# Create a simple selection interface
root = tk.Tk()
root.withdraw() # Hide the main window
messagebox.showinfo("Screenshot Selection",
"Instructions:\n"
"1. Close this dialog\n"
"2. Move mouse to top-left corner of desired region\n"
"3. Press and hold left mouse button\n"
"4. Drag to bottom-right corner\n"
"5. Release mouse button")
# Get mouse position for region selection
print("Move mouse to TOP-LEFT corner and press ENTER...")
input()
start_x, start_y = pyautogui.position()
print(f"Top-left: ({start_x}, {start_y})")
print("Move mouse to BOTTOM-RIGHT corner and press ENTER...")
input()
end_x, end_y = pyautogui.position()
print(f"Bottom-right: ({end_x}, {end_y})")
# Calculate region
left = min(start_x, end_x)
top = min(start_y, end_y)
width = abs(end_x - start_x)
height = abs(end_y - start_y)
if width < 10 or height < 10:
print("Region too small!")
return False
# Take screenshot of selected region
screenshot = pyautogui.screenshot(region=(left, top, width, height))
screenshot.save(output_path)
root.destroy()
return os.path.exists(output_path) and os.path.getsize(output_path) > 0
except ImportError:
print("PyAutoGUI library not installed. Install with: pip install pyautogui")
return False
except Exception as e:
print(f"Error taking interactive screenshot: {e}")
return False
def take_region_screenshot_cross_platform(
output_path: str,
method: str = "auto",
region: Optional[Tuple[int, int, int, int]] = None,
**kwargs
) -> bool:
"""
Universal cross-platform screenshot function that tries different methods.
Args:
output_path: Path where the screenshot will be saved
method: Method to use ('auto', 'mss', 'pyautogui', 'pillow', 'pyscreenshot', 'macos', 'interactive')
region: Region to capture (format depends on method)
**kwargs: Additional arguments for specific methods
Returns:
True if screenshot was taken successfully, False otherwise
"""
if method == "auto":
# Try methods in order of preference (speed and reliability)
methods_to_try = ["mss", "pillow", "pyautogui", "pyscreenshot"]
if sys.platform == "darwin": # macOS
methods_to_try.insert(0, "macos") # Prefer native macOS method
for auto_method in methods_to_try:
if take_region_screenshot_cross_platform(output_path, auto_method, region, **kwargs):
return True
print("All screenshot methods failed!")
return False
elif method == "mss":
# MSS doesn't support region selection directly, so we crop afterwards
if region and len(region) == 4:
# Take full screenshot first, then crop
temp_path = output_path + ".temp.png"
if take_region_screenshot_mss(temp_path, kwargs.get('monitor_number', 0)):
try:
img = Image.open(temp_path)
if len(region) == 4:
# Convert PyAutoGUI format (left, top, width, height) to PIL format (left, top, right, bottom)
left, top, width, height = region
right = left + width
bottom = top + height
cropped = img.crop((left, top, right, bottom))
else:
cropped = img.crop(region)
cropped.save(output_path)
os.remove(temp_path)
return True
except Exception as e:
print(f"Error cropping MSS screenshot: {e}")
if os.path.exists(temp_path):
os.remove(temp_path)
return False
else:
return take_region_screenshot_mss(output_path, kwargs.get('monitor_number', 0))
elif method == "pyautogui":
if region and len(region) == 4:
return take_region_screenshot_pyautogui(output_path, region)
else:
return take_region_screenshot_pyautogui(output_path)
elif method == "pillow":
return take_region_screenshot_pillow(output_path, region)
elif method == "pyscreenshot":
return take_region_screenshot_pyscreenshot(output_path, region, kwargs.get('backend', 'auto'))
elif method == "macos":
return take_region_screenshot(output_path) # Original macOS function
elif method == "interactive":
return take_region_screenshot_interactive_pyautogui(output_path)
else:
print(f"Unknown screenshot method: {method}")
return False
def take_region_screenshot(output_path: str) -> bool: def take_region_screenshot(output_path: str) -> bool:
""" """
Take a region screenshot on macOS using the built-in screencapture command. Take a region screenshot on macOS using the built-in screencapture command.
Generated
+201
View File
@@ -1182,6 +1182,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8e/a7/b276ff776533b423710a285c8168b52551cb2ab0855443131fdc7fd8c16f/easygui-0.98.3-py2.py3-none-any.whl", hash = "sha256:33498710c68b5376b459cd3fc48d1d1f33822139eb3ed01defbc0528326da3ba", size = 92655, upload-time = "2022-04-01T13:15:49.568Z" }, { url = "https://files.pythonhosted.org/packages/8e/a7/b276ff776533b423710a285c8168b52551cb2ab0855443131fdc7fd8c16f/easygui-0.98.3-py2.py3-none-any.whl", hash = "sha256:33498710c68b5376b459cd3fc48d1d1f33822139eb3ed01defbc0528326da3ba", size = 92655, upload-time = "2022-04-01T13:15:49.568Z" },
] ]
[[package]]
name = "easyprocess"
version = "1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/86/e5/1071ad7de469bf3baae5b04d6c8019876c819c2d428cc1b0f15b4b31fc89/EasyProcess-1.1.tar.gz", hash = "sha256:885898302a57aab948973e8b5d32a4229392b9fb2d986ab1d4ffd590e5ba90ec", size = 11829, upload-time = "2022-01-15T10:58:56.146Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9c/cf/27d1f4b3bae5e566f94fc716e048120128cf603d5163638d22bcd0fc92d8/EasyProcess-1.1-py3-none-any.whl", hash = "sha256:82eed523a0a5eb12a81fa4eacd9f342caeb3f900eb4b798740e6696ad07e63f9", size = 8660, upload-time = "2022-01-15T10:58:54.473Z" },
]
[[package]] [[package]]
name = "ebcdic" name = "ebcdic"
version = "1.1.1" version = "1.1.1"
@@ -1275,6 +1284,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/91/db/a0335710caaa6d0aebdaa65ad4df789c15d89b7babd9a30277838a7d9aac/emoji-2.14.1-py3-none-any.whl", hash = "sha256:35a8a486c1460addb1499e3bf7929d3889b2e2841a57401903699fef595e942b", size = 590617, upload-time = "2025-01-16T06:31:23.526Z" }, { url = "https://files.pythonhosted.org/packages/91/db/a0335710caaa6d0aebdaa65ad4df789c15d89b7babd9a30277838a7d9aac/emoji-2.14.1-py3-none-any.whl", hash = "sha256:35a8a486c1460addb1499e3bf7929d3889b2e2841a57401903699fef595e942b", size = 590617, upload-time = "2025-01-16T06:31:23.526Z" },
] ]
[[package]]
name = "entrypoint2"
version = "1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/41/2b/513088059a4bfe89acd8ddb74f9350b399507a0fe6676c3346d54449a5b1/entrypoint2-1.1.tar.gz", hash = "sha256:fc0b7fe7b21acdab47a585ab9407ca7e5c4f96cb6888575db6b0ceb91f0e105a", size = 13393, upload-time = "2022-06-11T06:28:21.619Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/42/ee/84c8990b08efa0265bd10fc8781ef26e3157715bf0dfa47ee3c056b513d4/entrypoint2-1.1-py2.py3-none-any.whl", hash = "sha256:eeb8c327bdb65cdd1668c023a6b110b7e3d1a046fb05e043861ebd9264b3a257", size = 9864, upload-time = "2022-06-11T06:28:19.529Z" },
]
[[package]] [[package]]
name = "et-xmlfile" name = "et-xmlfile"
version = "2.0.0" version = "2.0.0"
@@ -2277,6 +2295,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" },
] ]
[[package]]
name = "jeepney"
version = "0.9.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", size = 106758, upload-time = "2025-02-27T18:51:01.684Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010, upload-time = "2025-02-27T18:51:00.104Z" },
]
[[package]] [[package]]
name = "jinja2" name = "jinja2"
version = "3.1.6" version = "3.1.6"
@@ -2920,6 +2947,17 @@ s3 = [
{ name = "pyyaml" }, { name = "pyyaml" },
] ]
[[package]]
name = "mouseinfo"
version = "0.1.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyperclip" },
{ name = "python3-xlib", marker = "sys_platform == 'linux'" },
{ name = "rubicon-objc", marker = "sys_platform == 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850, upload-time = "2020-03-27T21:20:10.136Z" }
[[package]] [[package]]
name = "mpmath" name = "mpmath"
version = "1.3.0" version = "1.3.0"
@@ -2969,6 +3007,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/03/54/7f6d3d9acad083dae8c22d9ab483b657359a1bf56fee1d7af88794677707/msoffcrypto_tool-5.4.2-py3-none-any.whl", hash = "sha256:274fe2181702d1e5a107ec1b68a4c9fea997a44972ae1cc9ae0cb4f6a50fef0e", size = 48713, upload-time = "2024-08-08T15:50:27.093Z" }, { url = "https://files.pythonhosted.org/packages/03/54/7f6d3d9acad083dae8c22d9ab483b657359a1bf56fee1d7af88794677707/msoffcrypto_tool-5.4.2-py3-none-any.whl", hash = "sha256:274fe2181702d1e5a107ec1b68a4c9fea997a44972ae1cc9ae0cb4f6a50fef0e", size = 48713, upload-time = "2024-08-08T15:50:27.093Z" },
] ]
[[package]]
name = "mss"
version = "10.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/be/2c/6a50c69793918502b4391729bd5741964c9f8ccc98c8482d4a680384923b/mss-10.0.0.tar.gz", hash = "sha256:d903e0d51262bf0f8782841cf16eaa6d7e3e1f12eae35ab41c2e318837c6637f", size = 83127, upload-time = "2024-11-14T09:37:07.848Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/29/aa/b897ae9e1c1616e4df9fb319637ef6a9d07cca6d46de6b59c80209f006a4/mss-10.0.0-py3-none-any.whl", hash = "sha256:82cf6460a53d09e79b7b6d871163c982e6c7e9649c426e7b7591b74956d5cb64", size = 24050, upload-time = "2024-11-14T09:37:06.139Z" },
]
[[package]] [[package]]
name = "multidict" name = "multidict"
version = "6.6.3" version = "6.6.3"
@@ -4492,6 +4539,22 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/77/89/bc88a6711935ba795a679ea6ebee07e128050d6382eaa35a0a47c8032bdc/pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd", size = 181537, upload-time = "2024-09-11T16:02:10.336Z" }, { url = "https://files.pythonhosted.org/packages/77/89/bc88a6711935ba795a679ea6ebee07e128050d6382eaa35a0a47c8032bdc/pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd", size = 181537, upload-time = "2024-09-11T16:02:10.336Z" },
] ]
[[package]]
name = "pyautogui"
version = "0.9.54"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mouseinfo" },
{ name = "pygetwindow" },
{ name = "pymsgbox" },
{ name = "pyobjc-core", marker = "sys_platform == 'darwin'" },
{ name = "pyobjc-framework-quartz", marker = "sys_platform == 'darwin'" },
{ name = "pyscreeze" },
{ name = "python3-xlib", marker = "sys_platform == 'linux'" },
{ name = "pytweening" },
]
sdist = { url = "https://files.pythonhosted.org/packages/65/ff/cdae0a8c2118a0de74b6cf4cbcdcaf8fd25857e6c3f205ce4b1794b27814/PyAutoGUI-0.9.54.tar.gz", hash = "sha256:dd1d29e8fd118941cb193f74df57e5c6ff8e9253b99c7b04f39cfc69f3ae04b2", size = 61236, upload-time = "2023-05-24T20:11:32.972Z" }
[[package]] [[package]]
name = "pyclipper" name = "pyclipper"
version = "1.3.0.post6" version = "1.3.0.post6"
@@ -4629,6 +4692,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/1d/0d/95993c08c721ec68892547f2117e8f9dfbcef2ca71e098533541b4a54d5f/pyee-12.0.0-py3-none-any.whl", hash = "sha256:7b14b74320600049ccc7d0e0b1becd3b4bd0a03c745758225e31a59f4095c990", size = 14831, upload-time = "2024-08-30T19:40:42.132Z" }, { url = "https://files.pythonhosted.org/packages/1d/0d/95993c08c721ec68892547f2117e8f9dfbcef2ca71e098533541b4a54d5f/pyee-12.0.0-py3-none-any.whl", hash = "sha256:7b14b74320600049ccc7d0e0b1becd3b4bd0a03c745758225e31a59f4095c990", size = 14831, upload-time = "2024-08-30T19:40:42.132Z" },
] ]
[[package]]
name = "pygetwindow"
version = "0.0.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyrect" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e1/70/c7a4f46dbf06048c6d57d9489b8e0f9c4c3d36b7479f03c5ca97eaa2541d/PyGetWindow-0.0.9.tar.gz", hash = "sha256:17894355e7d2b305cd832d717708384017c1698a90ce24f6f7fbf0242dd0a688", size = 9699, upload-time = "2020-10-04T02:12:50.806Z" }
[[package]] [[package]]
name = "pygments" name = "pygments"
version = "2.19.2" version = "2.19.2"
@@ -4730,6 +4802,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b5/9c/00301a6df26f0f8d5c5955192892241e803742e7c3da8c2c222efabc0df6/pymongo-4.13.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c38168263ed94a250fc5cf9c6d33adea8ab11c9178994da1c3481c2a49d235f8", size = 1011057, upload-time = "2025-06-16T18:16:07.917Z" }, { url = "https://files.pythonhosted.org/packages/b5/9c/00301a6df26f0f8d5c5955192892241e803742e7c3da8c2c222efabc0df6/pymongo-4.13.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c38168263ed94a250fc5cf9c6d33adea8ab11c9178994da1c3481c2a49d235f8", size = 1011057, upload-time = "2025-06-16T18:16:07.917Z" },
] ]
[[package]]
name = "pymsgbox"
version = "1.0.9"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7d/ff/4c6f31a4f08979f12a663f2aeb6c8b765d3bd592e66eaaac445f547bb875/PyMsgBox-1.0.9.tar.gz", hash = "sha256:2194227de8bff7a3d6da541848705a155dcbb2a06ee120d9f280a1d7f51263ff", size = 18829, upload-time = "2020-10-11T01:51:43.227Z" }
[[package]] [[package]]
name = "pymysql" name = "pymysql"
version = "1.1.1" version = "1.1.1"
@@ -4739,6 +4817,55 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/94/e4181a1f6286f545507528c78016e00065ea913276888db2262507693ce5/PyMySQL-1.1.1-py3-none-any.whl", hash = "sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", size = 44972, upload-time = "2024-05-21T11:03:41.216Z" }, { url = "https://files.pythonhosted.org/packages/0c/94/e4181a1f6286f545507528c78016e00065ea913276888db2262507693ce5/PyMySQL-1.1.1-py3-none-any.whl", hash = "sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", size = 44972, upload-time = "2024-05-21T11:03:41.216Z" },
] ]
[[package]]
name = "pyobjc-core"
version = "11.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e8/e9/0b85c81e2b441267bca707b5d89f56c2f02578ef8f3eafddf0e0c0b8848c/pyobjc_core-11.1.tar.gz", hash = "sha256:b63d4d90c5df7e762f34739b39cc55bc63dbcf9fb2fb3f2671e528488c7a87fe", size = 974602, upload-time = "2025-06-14T20:56:34.189Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/a7/55afc166d89e3fcd87966f48f8bca3305a3a2d7c62100715b9ffa7153a90/pyobjc_core-11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ec36680b5c14e2f73d432b03ba7c1457dc6ca70fa59fd7daea1073f2b4157d33", size = 671075, upload-time = "2025-06-14T20:44:46.594Z" },
{ url = "https://files.pythonhosted.org/packages/c0/09/e83228e878e73bf756749939f906a872da54488f18d75658afa7f1abbab1/pyobjc_core-11.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:765b97dea6b87ec4612b3212258024d8496ea23517c95a1c5f0735f96b7fd529", size = 677985, upload-time = "2025-06-14T20:44:48.375Z" },
{ url = "https://files.pythonhosted.org/packages/c5/24/12e4e2dae5f85fd0c0b696404ed3374ea6ca398e7db886d4f1322eb30799/pyobjc_core-11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:18986f83998fbd5d3f56d8a8428b2f3e0754fd15cef3ef786ca0d29619024f2c", size = 676431, upload-time = "2025-06-14T20:44:49.908Z" },
{ url = "https://files.pythonhosted.org/packages/f7/79/031492497624de4c728f1857181b06ce8c56444db4d49418fa459cba217c/pyobjc_core-11.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:8849e78cfe6595c4911fbba29683decfb0bf57a350aed8a43316976ba6f659d2", size = 719330, upload-time = "2025-06-14T20:44:51.621Z" },
{ url = "https://files.pythonhosted.org/packages/ed/7d/6169f16a0c7ec15b9381f8bf33872baf912de2ef68d96c798ca4c6ee641f/pyobjc_core-11.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:8cb9ed17a8d84a312a6e8b665dd22393d48336ea1d8277e7ad20c19a38edf731", size = 667203, upload-time = "2025-06-14T20:44:53.262Z" },
{ url = "https://files.pythonhosted.org/packages/49/0f/f5ab2b0e57430a3bec9a62b6153c0e79c05a30d77b564efdb9f9446eeac5/pyobjc_core-11.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:f2455683e807f8541f0d83fbba0f5d9a46128ab0d5cc83ea208f0bec759b7f96", size = 708807, upload-time = "2025-06-14T20:44:54.851Z" },
]
[[package]]
name = "pyobjc-framework-cocoa"
version = "11.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyobjc-core", marker = "sys_platform == 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/4b/c5/7a866d24bc026f79239b74d05e2cf3088b03263da66d53d1b4cf5207f5ae/pyobjc_framework_cocoa-11.1.tar.gz", hash = "sha256:87df76b9b73e7ca699a828ff112564b59251bb9bbe72e610e670a4dc9940d038", size = 5565335, upload-time = "2025-06-14T20:56:59.683Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/90/43/6841046aa4e257b6276cd23e53cacedfb842ecaf3386bb360fa9cc319aa1/pyobjc_framework_cocoa-11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7b9a9b8ba07f5bf84866399e3de2aa311ed1c34d5d2788a995bdbe82cc36cfa0", size = 388177, upload-time = "2025-06-14T20:46:51.454Z" },
{ url = "https://files.pythonhosted.org/packages/68/da/41c0f7edc92ead461cced7e67813e27fa17da3c5da428afdb4086c69d7ba/pyobjc_framework_cocoa-11.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:806de56f06dfba8f301a244cce289d54877c36b4b19818e3b53150eb7c2424d0", size = 388983, upload-time = "2025-06-14T20:46:52.591Z" },
{ url = "https://files.pythonhosted.org/packages/4e/0b/a01477cde2a040f97e226f3e15e5ffd1268fcb6d1d664885a95ba592eca9/pyobjc_framework_cocoa-11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:54e93e1d9b0fc41c032582a6f0834befe1d418d73893968f3f450281b11603da", size = 389049, upload-time = "2025-06-14T20:46:53.757Z" },
{ url = "https://files.pythonhosted.org/packages/bc/e6/64cf2661f6ab7c124d0486ec6d1d01a9bb2838a0d2a46006457d8c5e6845/pyobjc_framework_cocoa-11.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:fd5245ee1997d93e78b72703be1289d75d88ff6490af94462b564892e9266350", size = 393110, upload-time = "2025-06-14T20:46:54.894Z" },
{ url = "https://files.pythonhosted.org/packages/33/87/01e35c5a3c5bbdc93d5925366421e10835fcd7b23347b6c267df1b16d0b3/pyobjc_framework_cocoa-11.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:aede53a1afc5433e1e7d66568cc52acceeb171b0a6005407a42e8e82580b4fc0", size = 392644, upload-time = "2025-06-14T20:46:56.503Z" },
{ url = "https://files.pythonhosted.org/packages/c1/7c/54afe9ffee547c41e1161691e72067a37ed27466ac71c089bfdcd07ca70d/pyobjc_framework_cocoa-11.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:1b5de4e1757bb65689d6dc1f8d8717de9ec8587eb0c4831c134f13aba29f9b71", size = 396742, upload-time = "2025-06-14T20:46:57.64Z" },
]
[[package]]
name = "pyobjc-framework-quartz"
version = "11.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyobjc-core", marker = "sys_platform == 'darwin'" },
{ name = "pyobjc-framework-cocoa", marker = "sys_platform == 'darwin'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c7/ac/6308fec6c9ffeda9942fef72724f4094c6df4933560f512e63eac37ebd30/pyobjc_framework_quartz-11.1.tar.gz", hash = "sha256:a57f35ccfc22ad48c87c5932818e583777ff7276605fef6afad0ac0741169f75", size = 3953275, upload-time = "2025-06-14T20:58:17.924Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/cb/38172fdb350b3f47e18d87c5760e50f4efbb4da6308182b5e1310ff0cde4/pyobjc_framework_quartz-11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2d501fe95ef15d8acf587cb7dc4ab4be3c5a84e2252017da8dbb7df1bbe7a72a", size = 215565, upload-time = "2025-06-14T20:53:35.262Z" },
{ url = "https://files.pythonhosted.org/packages/9b/37/ee6e0bdd31b3b277fec00e5ee84d30eb1b5b8b0e025095e24ddc561697d0/pyobjc_framework_quartz-11.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9ac806067541917d6119b98d90390a6944e7d9bd737f5c0a79884202327c9204", size = 216410, upload-time = "2025-06-14T20:53:36.346Z" },
{ url = "https://files.pythonhosted.org/packages/bd/27/4f4fc0e6a0652318c2844608dd7c41e49ba6006ee5fb60c7ae417c338357/pyobjc_framework_quartz-11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43a1138280571bbf44df27a7eef519184b5c4183a588598ebaaeb887b9e73e76", size = 216816, upload-time = "2025-06-14T20:53:37.358Z" },
{ url = "https://files.pythonhosted.org/packages/b8/8a/1d15e42496bef31246f7401aad1ebf0f9e11566ce0de41c18431715aafbc/pyobjc_framework_quartz-11.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b23d81c30c564adf6336e00b357f355b35aad10075dd7e837cfd52a9912863e5", size = 221941, upload-time = "2025-06-14T20:53:38.34Z" },
{ url = "https://files.pythonhosted.org/packages/32/a8/a3f84d06e567efc12c104799c7fd015f9bea272a75f799eda8b79e8163c6/pyobjc_framework_quartz-11.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:07cbda78b4a8fcf3a2d96e047a2ff01f44e3e1820f46f0f4b3b6d77ff6ece07c", size = 221312, upload-time = "2025-06-14T20:53:39.435Z" },
{ url = "https://files.pythonhosted.org/packages/76/ef/8c08d4f255bb3efe8806609d1f0b1ddd29684ab0f9ffb5e26d3ad7957b29/pyobjc_framework_quartz-11.1-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:39d02a3df4b5e3eee1e0da0fb150259476910d2a9aa638ab94153c24317a9561", size = 226353, upload-time = "2025-06-14T20:53:40.655Z" },
]
[[package]] [[package]]
name = "pypandoc" name = "pypandoc"
version = "1.15" version = "1.15"
@@ -4816,6 +4943,36 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" }, { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" },
] ]
[[package]]
name = "pyrect"
version = "0.2.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cb/04/2ba023d5f771b645f7be0c281cdacdcd939fe13d1deb331fc5ed1a6b3a98/PyRect-0.2.0.tar.gz", hash = "sha256:f65155f6df9b929b67caffbd57c0947c5ae5449d3b580d178074bffb47a09b78", size = 17219, upload-time = "2022-03-16T04:45:52.36Z" }
[[package]]
name = "pyscreenshot"
version = "3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "easyprocess" },
{ name = "entrypoint2" },
{ name = "jeepney", marker = "sys_platform == 'linux'" },
{ name = "mss" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f0/bf/a051bea0ad0fb9877684d0f8b87e0e55970b53b117db80c5f729d6dda762/pyscreenshot-3.1.tar.gz", hash = "sha256:8c0e93f0aef66a6bfe55a86abfced6bd396ae4b4f6cc1e36f04a28ad2625594d", size = 29238, upload-time = "2023-03-12T06:34:24.652Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c6/fb/acc0b5a7251682cd11c67c40a1532ffb1dda71626e9ad7e7ba1e55cc3ae2/pyscreenshot-3.1-py3-none-any.whl", hash = "sha256:73d406d41a0977125bdfd2f6488f0caf1394e84d1d4c1065d5e8b1400b307096", size = 28796, upload-time = "2023-03-12T06:34:22.549Z" },
]
[[package]]
name = "pyscreeze"
version = "1.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pillow", version = "11.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ee/f0/cb456ac4f1a73723d5b866933b7986f02bacea27516629c00f8e7da94c2d/pyscreeze-1.0.1.tar.gz", hash = "sha256:cf1662710f1b46aa5ff229ee23f367da9e20af4a78e6e365bee973cad0ead4be", size = 27826, upload-time = "2024-08-20T23:03:07.291Z" }
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "8.3.5" version = "8.3.5"
@@ -5022,6 +5179,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3c/32/b4fb8585d1be0f68bde7e110dffbcf354915f77ad8c778563f0ad9655c02/python_socketio-5.13.0-py3-none-any.whl", hash = "sha256:51f68d6499f2df8524668c24bcec13ba1414117cfb3a90115c559b601ab10caf", size = 77800, upload-time = "2025-04-12T15:46:58.412Z" }, { url = "https://files.pythonhosted.org/packages/3c/32/b4fb8585d1be0f68bde7e110dffbcf354915f77ad8c778563f0ad9655c02/python_socketio-5.13.0-py3-none-any.whl", hash = "sha256:51f68d6499f2df8524668c24bcec13ba1414117cfb3a90115c559b601ab10caf", size = 77800, upload-time = "2025-04-12T15:46:58.412Z" },
] ]
[[package]]
name = "python3-xlib"
version = "0.15"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ef/c6/2c5999de3bb1533521f1101e8fe56fd9c266732f4d48011c7c69b29d12ae/python3-xlib-0.15.tar.gz", hash = "sha256:dc4245f3ae4aa5949c1d112ee4723901ade37a96721ba9645f2bfa56e5b383f8", size = 132828, upload-time = "2014-05-31T12:28:59.603Z" }
[[package]] [[package]]
name = "pytube" name = "pytube"
version = "15.0.0" version = "15.0.0"
@@ -5031,6 +5194,12 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/51/64/bcf8632ed2b7a36bbf84a0544885ffa1d0b4bcf25cc0903dba66ec5fdad9/pytube-15.0.0-py3-none-any.whl", hash = "sha256:07b9904749e213485780d7eb606e5e5b8e4341aa4dccf699160876da00e12d78", size = 57594, upload-time = "2023-05-07T19:38:59.191Z" }, { url = "https://files.pythonhosted.org/packages/51/64/bcf8632ed2b7a36bbf84a0544885ffa1d0b4bcf25cc0903dba66ec5fdad9/pytube-15.0.0-py3-none-any.whl", hash = "sha256:07b9904749e213485780d7eb606e5e5b8e4341aa4dccf699160876da00e12d78", size = 57594, upload-time = "2023-05-07T19:38:59.191Z" },
] ]
[[package]]
name = "pytweening"
version = "1.2.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/79/0c/c16bc93ac2755bac0066a8ecbd2a2931a1735a6fffd99a2b9681c7e83e90/pytweening-1.2.0.tar.gz", hash = "sha256:243318b7736698066c5f362ec5c2b6434ecf4297c3c8e7caa8abfe6af4cac71b", size = 171241, upload-time = "2024-02-20T03:37:56.809Z" }
[[package]] [[package]]
name = "pytz" name = "pytz"
version = "2025.2" version = "2025.2"
@@ -5448,6 +5617,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b6/dd/641e9cf68d4242aaf7ce9653498009d8925080b6664993988bd50468932a/rtfde-0.1.2.1-py3-none-any.whl", hash = "sha256:c44dfa923a435c54cdbdd0e0f5352a4075542af317af061f82f2d4f032271645", size = 36260, upload-time = "2025-05-04T18:48:01.119Z" }, { url = "https://files.pythonhosted.org/packages/b6/dd/641e9cf68d4242aaf7ce9653498009d8925080b6664993988bd50468932a/rtfde-0.1.2.1-py3-none-any.whl", hash = "sha256:c44dfa923a435c54cdbdd0e0f5352a4075542af317af061f82f2d4f032271645", size = 36260, upload-time = "2025-05-04T18:48:01.119Z" },
] ]
[[package]]
name = "rubicon-objc"
version = "0.5.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e0/83/e57741dcf862a2581d53eccf8b11749c97f73d9754bbc538fb6c7b527da3/rubicon_objc-0.5.1.tar.gz", hash = "sha256:90bee9fc1de4515e17615e15648989b88bb8d4d2ffc8c7c52748272cd7f30a66", size = 174639, upload-time = "2025-06-03T06:33:50.822Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/58/0a/e451c3dbda38dd6abab1fd16c3b35623fc0635dffcbbf97f1acc55a58508/rubicon_objc-0.5.1-py3-none-any.whl", hash = "sha256:17092756241b8370231cfaad45ad6e8ce99534987f2acbc944d65df5bdf8f6cd", size = 63323, upload-time = "2025-06-03T06:33:48.863Z" },
]
[[package]] [[package]]
name = "s3transfer" name = "s3transfer"
version = "0.10.4" version = "0.10.4"
@@ -5943,6 +6121,22 @@ dependencies = [
{ name = "typer" }, { name = "typer" },
] ]
[package.optional-dependencies]
screenshot-all = [
{ name = "mss" },
{ name = "pyautogui" },
{ name = "pyscreenshot" },
]
screenshot-fast = [
{ name = "mss" },
]
screenshot-full = [
{ name = "pyautogui" },
]
screenshot-multi = [
{ name = "pyscreenshot" },
]
[package.dev-dependencies] [package.dev-dependencies]
dev = [ dev = [
{ name = "open-webui", version = "0.6.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" }, { name = "open-webui", version = "0.6.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" },
@@ -5951,12 +6145,19 @@ dev = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "mss", marker = "extra == 'screenshot-all'", specifier = ">=7.0.0" },
{ name = "mss", marker = "extra == 'screenshot-fast'", specifier = ">=7.0.0" },
{ name = "pillow", specifier = ">=11.1.0" }, { name = "pillow", specifier = ">=11.1.0" },
{ name = "pyautogui", marker = "extra == 'screenshot-all'", specifier = ">=0.9.54" },
{ name = "pyautogui", marker = "extra == 'screenshot-full'", specifier = ">=0.9.54" },
{ name = "pyperclip", specifier = ">=1.9.0" }, { name = "pyperclip", specifier = ">=1.9.0" },
{ name = "pyscreenshot", marker = "extra == 'screenshot-all'", specifier = ">=3.1" },
{ name = "pyscreenshot", marker = "extra == 'screenshot-multi'", specifier = ">=3.1" },
{ name = "python-doctr", specifier = ">=0.8.0" }, { name = "python-doctr", specifier = ">=0.8.0" },
{ name = "rich", specifier = ">=13.0.0" }, { name = "rich", specifier = ">=13.0.0" },
{ name = "typer", specifier = ">=0.12.0" }, { name = "typer", specifier = ">=0.12.0" },
] ]
provides-extras = ["screenshot-fast", "screenshot-full", "screenshot-multi", "screenshot-all"]
[package.metadata.requires-dev] [package.metadata.requires-dev]
dev = [{ name = "open-webui", specifier = ">=0.6.5" }] dev = [{ name = "open-webui", specifier = ">=0.6.5" }]