diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69d7850 --- /dev/null +++ b/.gitignore @@ -0,0 +1,278 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +*.lcov +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi/* +!.pixi/config.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule* +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# .idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ +# Temporary file for partial code execution +tempCodeRunnerFile.py + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml + +# General +.DS_Store +.localized +__MACOSX/ +.AppleDouble +.LSOverride +Icon[] + +# Resource forks +._* + +# Files and directories that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.com.apple.timemachine.supported +.PKInstallSandboxManager +.PKInstallSandboxManager-SystemSoftware +.hotfiles.btree +.vol +.file +.disk_label* +lost+found +.HFS+ Private Directory Data[] + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Mac OS 6 to 9 +Desktop DB +Desktop DF +TheFindByContentFolder +TheVolumeSettingsFolder +.FBCIndex +.FBCSemaphoreFile +.FBCLockFolder + +# Quota system +.quota.group +.quota.user +.quota.ops.group +.quota.ops.user + +# TimeMachine +Backups.backupdb +.MobileBackups +.MobileBackups.trash +MobileBackups.trash +tmbootpicker.efi \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..fdcfcfd --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12 \ No newline at end of file diff --git a/README.md b/README.md index 12a2d35..b79b9ab 100644 --- a/README.md +++ b/README.md @@ -1 +1,27 @@ -# AssaultCube ESP \ No newline at end of file +# AssaultCube ESP + +안녕하세요. +저는 이해할 수 있는 가이드를 쓸 자신이 없어요. +그러니까 그냥 여러분들이 사랑하시는 ChatGPT와 Gemini와 Claude에게 물어보세요. + +## 무엇이 필요한가요? +- [uv](https://docs.astral.sh/uv/) 패키지 매니저 +- [AssaultCube 게임](https://assault.cubers.net/) +- Windows + +## 설치 방법 +1. 이 저장소를 클론하거나 다운로드하세요. +2. 터미널에서 프로젝트 디렉토리로 이동하세요. +3. 다음 명령어를 실행하여 의존성을 설치하세요: + ```bash + uv sync + ``` +4. `main.py` 파일을 실행하여 ESP와 Aimbot을 시작하세요: + ```bash + uv run main.py + ``` + +## 사용 방법 +- 게임을 실행한 후, ESP와 Aimbot이 자동으로 활성화됩니다. +- 왼쪽 Shift 키를 누르고 있으면 Aimbot이 활성화되어 적을 자동으로 조준합니다. +- ESP는 적의 위치와 체력을 화면에 표시합니다. \ No newline at end of file diff --git a/libs/core.py b/libs/core.py new file mode 100644 index 0000000..fd7db1c --- /dev/null +++ b/libs/core.py @@ -0,0 +1,60 @@ +import sys +import pyMeow as pm +from pynput import keyboard + + +class Pointer: + local_player = 0x17E0A8 + entity_list = 0x18AC04 + player_count = 0x18AC0C + view_matrix = 0x17DFD0 + + +class ProcessManager: + """프로세스 및 모듈 초기화 관리""" + proc = None + base = None + + @classmethod + def initialize(cls): + """AssaultCube 프로세스 초기화""" + try: + cls.proc = pm.open_process("ac_client.exe") + cls.base = pm.get_module(cls.proc, "ac_client.exe")["base"] + print("Process and base initialized successfully.") + except Exception as e: + print(f"Error initializing process: {e}") + sys.exit(1) + + @classmethod + def get_proc(cls): + return cls.proc + + @classmethod + def get_base(cls): + return cls.base + + +class KeyboardManager: + """키보드 입력 관리""" + left_shift_pressed = False + + @classmethod + def setup(cls): + """키보드 리스너 시작""" + listener = keyboard.Listener(on_press=cls._on_press, on_release=cls._on_release) + listener.start() + + @classmethod + def _on_press(cls, key): + if key == keyboard.Key.shift_l: + cls.left_shift_pressed = True + + @classmethod + def _on_release(cls, key): + if key == keyboard.Key.shift_l: + cls.left_shift_pressed = False + + @classmethod + def is_left_shift_pressed(cls): + return cls.left_shift_pressed diff --git a/main.py b/main.py new file mode 100644 index 0000000..c9de859 --- /dev/null +++ b/main.py @@ -0,0 +1,57 @@ +import pyMeow as pm +from libs.core import Pointer, ProcessManager, KeyboardManager +from modules.esp import Entity, init_colors as init_esp_colors +from modules.aimbot import do_aimbot + +def init(): + ProcessManager.initialize() + KeyboardManager.setup() + + print("Starting ESP + Aimbot (Hold Right Shift) overlay...") + pm.overlay_init(target="AssaultCube", fps=144, trackTarget=True) + init_esp_colors() + + +def main(): + proc = ProcessManager.get_proc() + base = ProcessManager.get_base() + + while pm.overlay_loop(): + pm.begin_drawing() + pm.draw_fps(10, 10) + + try: + player_count = pm.r_int(proc, base + Pointer.player_count) + local_player_addr = pm.r_int(proc, base + Pointer.local_player) + my_team = pm.r_int(proc, local_player_addr + 0x30C) # team offset + + valid_entities = [] + + if player_count > 1: + ent_list = pm.r_int(proc, base + Pointer.entity_list) + ent_buffer = pm.r_ints(proc, ent_list, player_count)[1:] + v_matrix = pm.r_floats(proc, base + Pointer.view_matrix, 16) + + for addr in ent_buffer: + if addr == 0: continue + try: + ent = Entity(proc, addr) + valid_entities.append(ent) + if ent.wts(v_matrix): + ent.draw_box() + ent.draw_name() + ent.draw_health() + except: + continue + + # 에임봇 실행 + do_aimbot(proc, valid_entities, local_player_addr, my_team, KeyboardManager.is_left_shift_pressed()) + + except Exception as e: + pass + + pm.end_drawing() + +if __name__ == "__main__": + init() + main() diff --git a/modules/aimbot.py b/modules/aimbot.py new file mode 100644 index 0000000..a5af6c0 --- /dev/null +++ b/modules/aimbot.py @@ -0,0 +1,47 @@ +import math +import pyMeow as pm + +# Aimbot 오프셋 +class AimbotOffsets: + pos = 0x4 # Head position + yaw = 0x34 # camera_x + pitch = 0x38 # camera_y + +def do_aimbot(proc, entities, local_player_addr, my_team, left_shift_pressed): + if not left_shift_pressed or not entities: + return + + try: + my_pos = pm.r_vec3(proc, local_player_addr + AimbotOffsets.pos) + + target = None + min_dist = float('inf') + + screen_center_x = pm.get_screen_width() / 2 + screen_center_y = pm.get_screen_height() / 2 + + for ent in entities: + if ent.team == my_team or ent.health <= 0: + continue + + if ent.pos2d: + dist_to_crosshair = math.hypot(ent.pos2d["x"] - screen_center_x, ent.pos2d["y"] - screen_center_y) + if dist_to_crosshair < min_dist: + min_dist = dist_to_crosshair + target = ent + + if target: + dx = target.pos3d["x"] - my_pos["x"] + dy = target.pos3d["y"] - my_pos["y"] + dz = target.pos3d["z"] - my_pos["z"] + + distance = math.hypot(dx, dy) + + yaw = math.atan2(dy, dx) * 180 / math.pi + 90 + pitch = math.atan2(dz, distance) * 180 / math.pi + + pm.w_float(proc, local_player_addr + AimbotOffsets.yaw, yaw) + pm.w_float(proc, local_player_addr + AimbotOffsets.pitch, pitch) + + except Exception as e: + pass diff --git a/modules/esp.py b/modules/esp.py new file mode 100644 index 0000000..1b09d5c --- /dev/null +++ b/modules/esp.py @@ -0,0 +1,99 @@ +import pyMeow as pm + +# ESP 오프셋 +class ESPOffsets: + name = 0x205 + health = 0xEC + armor = 0xF0 + team = 0x30C + pos = 0x4 # Head position + fpos = 0x28 # Foot position + +# 색상 +class Colors: + cyan = None + orange = None + white = None + black = None + +def init_colors(): + """오버레이 초기화 후 색상을 초기화합니다.""" + Colors.cyan = pm.get_color("cyan") + Colors.orange = pm.get_color("orange") + Colors.white = pm.get_color("white") + Colors.black = pm.get_color("black") + +class Entity: + def __init__(self, proc, addr): + self.proc = proc + self.addr = addr + + self.health = pm.r_int(proc, addr + ESPOffsets.health) + if self.health <= 0 or self.health > 10000: + raise Exception("Entity is not alive or invalid.") + self.name = pm.r_string(proc, addr + ESPOffsets.name) + self.armor = pm.r_int(proc, addr + ESPOffsets.armor) + self.team = pm.r_int(proc, addr + ESPOffsets.team) + self.color = Colors.cyan if self.team else Colors.orange + self.pos3d = pm.r_vec3(proc, self.addr + ESPOffsets.pos) + self.fpos3d = pm.r_vec3(proc, self.addr + ESPOffsets.fpos) + self.pos2d = self.fpos2d = None + self.head = self.width = self.center = None + + def wts(self, vm): + try: + self.pos2d = pm.world_to_screen(vm, self.pos3d) + self.fpos2d = pm.world_to_screen(vm, self.fpos3d) + self.head = self.fpos2d["y"] - self.pos2d["y"] + self.width = self.head / 2 + self.center = self.width / 2 + return True + except: + return False + + def draw_box(self): + pm.draw_rectangle( + posX=self.pos2d["x"] - self.center, + posY=self.pos2d["y"] - self.center / 2, + width=self.width, + height=self.head + self.center / 2, + color=pm.fade_color(self.color, 0.3), + ) + pm.draw_rectangle_lines( + posX=self.pos2d["x"] - self.center, + posY=self.pos2d["y"] - self.center / 2, + width=self.width, + height=self.head + self.center / 2, + color=self.color, + lineThick=1.2, + ) + + def draw_name(self): + text_size = pm.measure_text(self.name, 15) / 2 + pm.draw_text( + text=self.name, + posX=self.pos2d["x"] - text_size, + posY=self.pos2d["y"], + fontSize=15, + color=Colors.white, + ) + + def draw_health(self): + pm.draw_circle_sector( + centerX=self.pos2d["x"] - self.center, + centerY=self.pos2d["y"] - self.center / 2, + radius=self.center / 3 + 2, + startAngle=0, + endAngle=360, + segments=0, + color=Colors.black, + ) + pm.draw_circle_sector( + centerX=self.pos2d["x"] - self.center, + centerY=self.pos2d["y"] - self.center / 2, + radius=self.center / 3, + startAngle=0, + endAngle=360 / 100 * min(self.health, 100), + segments=0, + color=self.color, + ) diff --git a/packages/pyMeow-1.73.42.zip b/packages/pyMeow-1.73.42.zip new file mode 100644 index 0000000..de33375 Binary files /dev/null and b/packages/pyMeow-1.73.42.zip differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3301388 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "assaultcube-esp" +version = "0.1.0" +description = "Cool Hack" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "pymeow", + "pynput>=1.8.2", +] + +[tool.uv.sources] +pymeow = { path = "packages/pyMeow-1.73.42.zip" } diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..ea381f7 --- /dev/null +++ b/uv.lock @@ -0,0 +1,150 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "assaultcube-esp" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "pymeow" }, + { name = "pynput" }, +] + +[package.metadata] +requires-dist = [ + { name = "pymeow", path = "packages/pyMeow-1.73.42.zip" }, + { name = "pynput", specifier = ">=1.8.2" }, +] + +[[package]] +name = "evdev" +version = "1.9.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/f5/397b61091120a9ca5001041dd7bf76c385b3bfd67a0e5bcb74b852bd22a4/evdev-1.9.3.tar.gz", hash = "sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9", size = 32723, upload-time = "2026-02-05T21:54:24.987Z" } + +[[package]] +name = "pymeow" +version = "1.73.42" +source = { path = "packages/pyMeow-1.73.42.zip" } +sdist = { hash = "sha256:93ee191f67cead633c58c20d1fd31b17bb2e4e83510f9d1b2b729f3a8a5a5fd6" } + +[[package]] +name = "pynput" +version = "1.8.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "evdev", marker = "'linux' in sys_platform" }, + { name = "pyobjc-framework-applicationservices", marker = "sys_platform == 'darwin'" }, + { name = "pyobjc-framework-quartz", marker = "sys_platform == 'darwin'" }, + { name = "python-xlib", marker = "'linux' in sys_platform" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/c6/e2d415610cfbc78308bee44218a46124aaa3301b1df08814df819b2254a1/pynput-1.8.2.tar.gz", hash = "sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087", size = 82818, upload-time = "2026-05-12T19:11:39.464Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/98/bbeb760852adb27f166ce1617f0e51aabb15f21b1e60ea703f2aed3c78ac/pynput-1.8.2-py2.py3-none-any.whl", hash = "sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1", size = 92028, upload-time = "2026-05-12T19:11:37.89Z" }, +] + +[[package]] +name = "pyobjc-core" +version = "12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/b6/d5612eb40be4fd5ef88c259339e6313f46ba67577a95d86c3470b951fce0/pyobjc_core-12.1.tar.gz", hash = "sha256:2bb3903f5387f72422145e1466b3ac3f7f0ef2e9960afa9bcd8961c5cbf8bd21", size = 1000532, upload-time = "2025-11-14T10:08:28.292Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/5a/6b15e499de73050f4a2c88fff664ae154307d25dc04da8fb38998a428358/pyobjc_core-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:818bcc6723561f207e5b5453efe9703f34bc8781d11ce9b8be286bb415eb4962", size = 678335, upload-time = "2025-11-14T09:32:20.107Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d2/29e5e536adc07bc3d33dd09f3f7cf844bf7b4981820dc2a91dd810f3c782/pyobjc_core-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:01c0cf500596f03e21c23aef9b5f326b9fb1f8f118cf0d8b66749b6cf4cbb37a", size = 677370, upload-time = "2025-11-14T09:33:05.273Z" }, + { url = "https://files.pythonhosted.org/packages/1b/f0/4b4ed8924cd04e425f2a07269943018d43949afad1c348c3ed4d9d032787/pyobjc_core-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:177aaca84bb369a483e4961186704f64b2697708046745f8167e818d968c88fc", size = 719586, upload-time = "2025-11-14T09:33:53.302Z" }, + { url = "https://files.pythonhosted.org/packages/25/98/9f4ed07162de69603144ff480be35cd021808faa7f730d082b92f7ebf2b5/pyobjc_core-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:844515f5d86395b979d02152576e7dee9cc679acc0b32dc626ef5bda315eaa43", size = 670164, upload-time = "2025-11-14T09:34:37.458Z" }, + { url = "https://files.pythonhosted.org/packages/62/50/dc076965c96c7f0de25c0a32b7f8aa98133ed244deaeeacfc758783f1f30/pyobjc_core-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:453b191df1a4b80e756445b935491b974714456ae2cbae816840bd96f86db882", size = 712204, upload-time = "2025-11-14T09:35:24.148Z" }, +] + +[[package]] +name = "pyobjc-framework-applicationservices" +version = "12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-coretext" }, + { name = "pyobjc-framework-quartz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/6a/d4e613c8e926a5744fc47a9e9fea08384a510dc4f27d844f7ad7a2d793bd/pyobjc_framework_applicationservices-12.1.tar.gz", hash = "sha256:c06abb74f119bc27aeb41bf1aef8102c0ae1288aec1ac8665ea186a067a8945b", size = 103247, upload-time = "2025-11-14T10:08:52.18Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/a7/55fa88def5c02732c4b747606ff1cbce6e1f890734bbd00f5596b21eaa02/pyobjc_framework_applicationservices-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c8f6e2fb3b3e9214ab4864ef04eee18f592b46a986c86ea0113448b310520532", size = 32835, upload-time = "2025-11-14T09:36:11.855Z" }, + { url = "https://files.pythonhosted.org/packages/fc/21/79e42ee836f1010f5fe9e97d2817a006736bd287c15a3674c399190a2e77/pyobjc_framework_applicationservices-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bd1f4dbb38234a24ae6819f5e22485cf7dd3dd4074ff3bf9a9fdb4c01a3b4a38", size = 32859, upload-time = "2025-11-14T09:36:15.208Z" }, + { url = "https://files.pythonhosted.org/packages/66/3a/0f1d4dcf2345e875e5ea9761d5a70969e241d24089133d21f008dde596f5/pyobjc_framework_applicationservices-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:8a5d2845249b6a85ba9e320a9848468c3f8cd6f59605a9a43f406a7810eaa830", size = 33115, upload-time = "2025-11-14T09:36:18.384Z" }, + { url = "https://files.pythonhosted.org/packages/40/44/3196b40fec68b4413c92875311f17ccf4c3ff7d2e53676f8fc18ad29bd18/pyobjc_framework_applicationservices-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:f43c9a24ad97a9121276d4d571aa04a924282c80d7291cfb3b29839c3e2013a8", size = 32997, upload-time = "2025-11-14T09:36:21.58Z" }, + { url = "https://files.pythonhosted.org/packages/fd/bb/dab21d2210d3ef7dd0616df7e8ea89b5d8d62444133a25f76e649a947168/pyobjc_framework_applicationservices-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:1f72e20009a4ebfd5ed5b23dc11c1528ad6b55cc63ee71952ddb2a5e5f1cb7da", size = 33238, upload-time = "2025-11-14T09:36:24.751Z" }, +] + +[[package]] +name = "pyobjc-framework-cocoa" +version = "12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyobjc-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/bf/ee4f27ec3920d5c6fc63c63e797c5b2cc4e20fe439217085d01ea5b63856/pyobjc_framework_cocoa-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:547c182837214b7ec4796dac5aee3aa25abc665757b75d7f44f83c994bcb0858", size = 384590, upload-time = "2025-11-14T09:41:17.336Z" }, + { url = "https://files.pythonhosted.org/packages/ad/31/0c2e734165abb46215797bd830c4bdcb780b699854b15f2b6240515edcc6/pyobjc_framework_cocoa-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5a3dcd491cacc2f5a197142b3c556d8aafa3963011110102a093349017705118", size = 384689, upload-time = "2025-11-14T09:41:41.478Z" }, + { url = "https://files.pythonhosted.org/packages/23/3b/b9f61be7b9f9b4e0a6db18b3c35c4c4d589f2d04e963e2174d38c6555a92/pyobjc_framework_cocoa-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:914b74328c22d8ca261d78c23ef2befc29776e0b85555973927b338c5734ca44", size = 388843, upload-time = "2025-11-14T09:42:05.719Z" }, + { url = "https://files.pythonhosted.org/packages/59/bb/f777cc9e775fc7dae77b569254570fe46eb842516b3e4fe383ab49eab598/pyobjc_framework_cocoa-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:03342a60fc0015bcdf9b93ac0b4f457d3938e9ef761b28df9564c91a14f0129a", size = 384932, upload-time = "2025-11-14T09:42:29.771Z" }, + { url = "https://files.pythonhosted.org/packages/58/27/b457b7b37089cad692c8aada90119162dfb4c4a16f513b79a8b2b022b33b/pyobjc_framework_cocoa-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6ba1dc1bfa4da42d04e93d2363491275fb2e2be5c20790e561c8a9e09b8cf2cc", size = 388970, upload-time = "2025-11-14T09:42:53.964Z" }, +] + +[[package]] +name = "pyobjc-framework-coretext" +version = "12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, + { name = "pyobjc-framework-quartz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/da/682c9c92a39f713bd3c56e7375fa8f1b10ad558ecb075258ab6f1cdd4a6d/pyobjc_framework_coretext-12.1.tar.gz", hash = "sha256:e0adb717738fae395dc645c9e8a10bb5f6a4277e73cba8fa2a57f3b518e71da5", size = 90124, upload-time = "2025-11-14T10:14:38.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/0f/ddf45bf0e3ba4fbdc7772de4728fd97ffc34a0b5a15e1ab1115b202fe4ae/pyobjc_framework_coretext-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d246fa654bdbf43bae3969887d58f0b336c29b795ad55a54eb76397d0e62b93c", size = 30108, upload-time = "2025-11-14T09:47:04.228Z" }, + { url = "https://files.pythonhosted.org/packages/20/a2/a3974e3e807c68e23a9d7db66fc38ac54f7ecd2b7a9237042006699a76e1/pyobjc_framework_coretext-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7cbb2c28580e6704ce10b9a991ccd9563a22b3a75f67c36cf612544bd8b21b5f", size = 30110, upload-time = "2025-11-14T09:47:07.518Z" }, + { url = "https://files.pythonhosted.org/packages/0f/5d/85e059349e9cfbd57269a1f11f56747b3ff5799a3bcbd95485f363c623d8/pyobjc_framework_coretext-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:14100d1e39efb30f57869671fb6fce8d668f80c82e25e7930fb364866e5c0dab", size = 30697, upload-time = "2025-11-14T09:47:10.932Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c3/adf9d306e9ead108167ab7a974ab7d171dbacf31c72fad63e12585f58023/pyobjc_framework_coretext-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:782a1a9617ea267c05226e9cd81a8dec529969a607fe1e037541ee1feb9524e9", size = 30095, upload-time = "2025-11-14T09:47:13.893Z" }, + { url = "https://files.pythonhosted.org/packages/bd/ca/6321295f47a47b0fca7de7e751ddc0ddc360413f4e506335fe9b0f0fb085/pyobjc_framework_coretext-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:7afe379c5a870fa3e66e6f65231c3c1732d9ccd2cd2a4904b2cd5178c9e3c562", size = 30702, upload-time = "2025-11-14T09:47:17.292Z" }, +] + +[[package]] +name = "pyobjc-framework-quartz" +version = "12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyobjc-core" }, + { name = "pyobjc-framework-cocoa" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/94/18/cc59f3d4355c9456fc945eae7fe8797003c4da99212dd531ad1b0de8a0c6/pyobjc_framework_quartz-12.1.tar.gz", hash = "sha256:27f782f3513ac88ec9b6c82d9767eef95a5cf4175ce88a1e5a65875fee799608", size = 3159099, upload-time = "2025-11-14T10:21:24.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/9b/780f057e5962f690f23fdff1083a4cfda5a96d5b4d3bb49505cac4f624f2/pyobjc_framework_quartz-12.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7730cdce46c7e985535b5a42c31381af4aa6556e5642dc55b5e6597595e57a16", size = 218798, upload-time = "2025-11-14T10:00:01.236Z" }, + { url = "https://files.pythonhosted.org/packages/ba/2d/e8f495328101898c16c32ac10e7b14b08ff2c443a756a76fd1271915f097/pyobjc_framework_quartz-12.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:629b7971b1b43a11617f1460cd218bd308dfea247cd4ee3842eb40ca6f588860", size = 219206, upload-time = "2025-11-14T10:00:15.623Z" }, + { url = "https://files.pythonhosted.org/packages/67/43/b1f0ad3b842ab150a7e6b7d97f6257eab6af241b4c7d14cb8e7fde9214b8/pyobjc_framework_quartz-12.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:53b84e880c358ba1ddcd7e8d5ea0407d760eca58b96f0d344829162cda5f37b3", size = 224317, upload-time = "2025-11-14T10:00:30.703Z" }, + { url = "https://files.pythonhosted.org/packages/4a/00/96249c5c7e5aaca5f688ca18b8d8ad05cd7886ebd639b3c71a6a4cadbe75/pyobjc_framework_quartz-12.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:42d306b07f05ae7d155984503e0fb1b701fecd31dcc5c79fe8ab9790ff7e0de0", size = 219558, upload-time = "2025-11-14T10:00:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a6/708a55f3ff7a18c403b30a29a11dccfed0410485a7548c60a4b6d4cc0676/pyobjc_framework_quartz-12.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0cc08fddb339b2760df60dea1057453557588908e42bdc62184b6396ce2d6e9a", size = 224580, upload-time = "2025-11-14T10:01:00.091Z" }, +] + +[[package]] +name = "python-xlib" +version = "0.33" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/f5/8c0653e5bb54e0cbdfe27bf32d41f27bc4e12faa8742778c17f2a71be2c0/python-xlib-0.33.tar.gz", hash = "sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32", size = 269068, upload-time = "2022-12-25T18:53:00.824Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/b8/ff33610932e0ee81ae7f1269c890f697d56ff74b9f5b2ee5d9b7fa2c5355/python_xlib-0.33-py2.py3-none-any.whl", hash = "sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398", size = 182185, upload-time = "2022-12-25T18:52:58.662Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +]