├── .circleci └── config.yml ├── .flake8 ├── .gitattributes ├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── README.md ├── cmus_osx ├── __init__.py ├── constants.py ├── env.py ├── payload │ ├── media_keys.py │ └── notify.py ├── resource │ └── icon.png └── util.py ├── poetry.lock └── pyproject.toml /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/python:3.7.5 6 | environment: 7 | POETRY_VERSION: 1.0.0b9 8 | steps: 9 | - checkout 10 | - run: 11 | command: | 12 | sudo chown -R circleci:circleci /usr/local/bin 13 | sudo chown -R circleci:circleci /usr/local/lib/python3.7/site-packages 14 | - run: 15 | name: Setup 16 | command: | 17 | sudo pip install poetry==${POETRY_VERSION} 18 | sudo pip install pre-commit 19 | mkdir -p /home/circleci/.config/pypoetry/ 20 | echo "[repositories]" > /home/circleci/.config/pypoetry/config.toml 21 | poetry config virtualenvs.create false 22 | pre-commit install-hooks 23 | - run: 24 | name: Lint 25 | command: pre-commit run --all-files 26 | - run: 27 | name: Build 28 | command: | 29 | poetry build 30 | - store_artifacts: 31 | path: dist 32 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501,W503,E203,E402 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.png filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *,cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask stuff: 59 | instance/ 60 | .webassets-cache 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # Jupyter Notebook 72 | .ipynb_checkpoints 73 | 74 | # pyenv 75 | .python-version 76 | 77 | # celery beat schedule file 78 | celerybeat-schedule 79 | 80 | # dotenv 81 | .env 82 | 83 | # virtualenv 84 | .venv/ 85 | venv/ 86 | ENV/ 87 | 88 | # Spyder project settings 89 | .spyderproject 90 | 91 | # Rope project settings 92 | .ropeproject 93 | 94 | .mypy_cache -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/ambv/black 3 | rev: 18.9b0 4 | hooks: 5 | - id: black 6 | - repo: https://github.com/asottile/blacken-docs 7 | rev: v0.3.0 8 | hooks: 9 | - id: blacken-docs 10 | additional_dependencies: [black==18.9b0] 11 | - repo: https://github.com/pre-commit/pre-commit-hooks 12 | rev: v2.1.0 13 | hooks: 14 | - id: trailing-whitespace 15 | args: [--markdown-linebreak-ext=md] 16 | - id: check-ast 17 | - id: check-added-large-files 18 | - repo: https://github.com/asottile/reorder_python_imports 19 | rev: v1.3.4 20 | hooks: 21 | - id: reorder-python-imports 22 | - repo: https://gitlab.com/pycqa/flake8 23 | rev: '3.7.6' 24 | hooks: 25 | - id: flake8 26 | - repo: https://github.com/pre-commit/mirrors-mypy 27 | rev: 'v0.670' 28 | hooks: 29 | - id: mypy -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Philip Trauner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | 5 |

cmus-osx

6 | 7 | ![Python version support: 3.7](https://img.shields.io/badge/python-3.7-limegreen.svg) 8 | [![PyPI version](https://badge.fury.io/py/cmus-osx.svg)](https://badge.fury.io/py/cmus-osx) 9 | ![License: MIT](https://img.shields.io/badge/license-MIT-limegreen.svg) 10 | [![CircleCI](https://circleci.com/gh/PhilipTrauner/cmus-osx.svg?style=svg)](https://circleci.com/gh/PhilipTrauner/cmus-osx) 11 | 12 | **cmus-osx** adds track change notifications, and media key support to [*cmus*](https://cmus.github.io/) (*macOS* only). 13 | 14 | ## Installation 15 | macOS automatically launches iTunes on media key presses. 16 | Installing [noTunes](https://github.com/tombonez/noTunes/releases/tag/v2.0) is the recommended solution to prevent this from happening. 17 | 18 | ```bash 19 | pip3 install cmus-osx 20 | cmus-osx install 21 | ``` 22 | 23 | **cmus-osx** supports virtual environments natively, so installing it via `pipx` (or basically any other virtual environment manager) works just as well. 24 | 25 | ### Uninstall 26 | ``` 27 | cmus-osx uninstall 28 | pip3 uninstall cmus-osx 29 | ``` 30 | 31 | #### pyenv 32 | Framework building has to be enabled, otherwise notifications cannot be created. 33 | ```bash 34 | export PYTHON_CONFIGURE_OPTS="--enable-framework" 35 | ``` 36 | 37 | ## Configuration 38 | ``` 39 | cmus-osx config 40 | ``` 41 | 42 | ### Credits 43 | * [azadkuh](https://github.com/azadkuh): all versions up to and including v1.2.0 44 | * [PhilipTrauner](https://github.com/PhilipTrauner): all following versions 45 | -------------------------------------------------------------------------------- /cmus_osx/__init__.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from os import chmod 3 | from os import kill 4 | from os import remove 5 | from os import rename 6 | from pathlib import Path 7 | from shutil import rmtree 8 | from signal import SIGTERM 9 | from subprocess import call 10 | from tempfile import NamedTemporaryFile 11 | from typing import Optional 12 | 13 | import click 14 | from click import echo 15 | from click import style 16 | 17 | from .constants import AUTOSAVE_MISSING 18 | from .constants import CMUS_OSX_FOLDER_NAME 19 | from .constants import CONFIG_NAME 20 | from .constants import COULD_NOT_LOCATED_CMUS_DIRECTORY 21 | from .constants import ENV 22 | from .constants import ENV_VAR_PREFIX 23 | from .constants import RC_ENTRY_REGEX 24 | from .constants import RC_SCRIPT_NAME 25 | from .constants import SCRIPTS 26 | from .constants import SDP_SCRIPT_NAME 27 | from .constants import STATUS_DISPLAY_PROGRAM_REGEX 28 | from .env import template 29 | from .util import get_cmus_instances 30 | from .util import locate_cmus_base_path 31 | from .util import locate_editor 32 | from .util import unexpanduser 33 | 34 | 35 | class CmusConfig: 36 | @dataclass 37 | class _CmusConfig: 38 | base_path: Path 39 | # File that holds cmus commands that are executed on startup 40 | rc_path: Path 41 | # cmus config file 42 | autosave_path: Path 43 | 44 | def __new__(self) -> Optional["CmusConfig._CmusConfig"]: # type: ignore 45 | base_path = locate_cmus_base_path() 46 | if base_path is not None: 47 | return CmusConfig._CmusConfig( 48 | base_path, base_path / "rc", base_path / "autosave" 49 | ) 50 | else: 51 | return None 52 | 53 | 54 | @click.group() 55 | @click.pass_context 56 | def entrypoint(ctx): 57 | # Entrypoint is called directly 58 | ctx.ensure_object(dict) 59 | 60 | cmus_config = CmusConfig() 61 | 62 | if cmus_config is not None: 63 | cmus_osx_base_path = cmus_config.base_path / CMUS_OSX_FOLDER_NAME 64 | cmus_osx_base_path.mkdir(exist_ok=True) 65 | 66 | config_path = cmus_osx_base_path / CONFIG_NAME 67 | if not config_path.is_file(): 68 | with open(config_path, "w") as f: 69 | f.write(template(ENV_VAR_PREFIX, ENV)) 70 | 71 | if not cmus_config.rc_path.is_file(): 72 | cmus_config.rc_path.touch() 73 | 74 | if not cmus_config.autosave_path.is_file(): 75 | echo( 76 | f"{style('ERROR', fg='red')}: cmus config file missing (launch cmus at least once " 77 | "before attempting installation)" 78 | ) 79 | exit(AUTOSAVE_MISSING) 80 | 81 | rc_script_path = cmus_config.base_path / CMUS_OSX_FOLDER_NAME / RC_SCRIPT_NAME 82 | sdp_script_path = cmus_config.base_path / CMUS_OSX_FOLDER_NAME / SDP_SCRIPT_NAME 83 | 84 | locals_ = locals() 85 | for local in (local for local in locals_ if local != "ctx"): 86 | ctx.obj[local] = locals_[local] 87 | else: 88 | echo(f"{style('ERROR', fg='red')}: Could not locate cmus config directory") 89 | 90 | exit(COULD_NOT_LOCATED_CMUS_DIRECTORY) 91 | 92 | 93 | @entrypoint.command() 94 | @click.option("-f", "--force", is_flag=True) 95 | @click.pass_context 96 | def install(ctx, force): 97 | cmus_config = ctx.obj["cmus_config"] 98 | cmus_osx_base_path = ctx.obj["cmus_osx_base_path"] 99 | rc_script_path = ctx.obj["rc_script_path"] 100 | sdp_script_path = ctx.obj["sdp_script_path"] 101 | 102 | cmus_osx_base_path.mkdir(exist_ok=True) 103 | 104 | for script_name in SCRIPTS: 105 | script_path = cmus_osx_base_path / script_name 106 | with open(script_path, "w") as f: 107 | f.write(f"{SCRIPTS[script_name]}\n") 108 | chmod(script_path, 0o744) 109 | 110 | write_rc = True 111 | 112 | unexpanded_rc_script_path = unexpanduser(rc_script_path) 113 | 114 | tmp_rc_file = NamedTemporaryFile("w", delete=False) 115 | with open(cmus_config.rc_path, "r") as f: 116 | for line in f: 117 | match = RC_ENTRY_REGEX.match(line) 118 | # Found invocation of 'rc' script 119 | if match is not None and Path(match.group(1)) in ( 120 | rc_script_path, 121 | unexpanded_rc_script_path, 122 | ): 123 | write_rc = False 124 | tmp_rc_file.write(line) 125 | 126 | if write_rc: 127 | tmp_rc_file.write(f"shell {str(unexpanded_rc_script_path)} &\n") 128 | rename(tmp_rc_file.name, cmus_config.rc_path) 129 | else: 130 | remove(tmp_rc_file.name) 131 | 132 | write_autosave = False 133 | 134 | unexpand_sdp_script_path = unexpanduser(sdp_script_path) 135 | 136 | tmp_autosave_file = NamedTemporaryFile("w", delete=False) 137 | with open(cmus_config.autosave_path, "r") as f: 138 | for line in f: 139 | match = STATUS_DISPLAY_PROGRAM_REGEX.match(line) 140 | if match is not None: 141 | sdp_value = match.group(1) 142 | # 'status_display_program' is not set 143 | if sdp_value == "": 144 | # Write 'status_display_program' without asking for permission 145 | write_autosave = True 146 | elif Path(sdp_value) not in (sdp_script_path, unexpand_sdp_script_path): 147 | # Ask for permission 148 | if force or click.confirm( 149 | f"{style('WARNING', fg='yellow')}: " 150 | f"'status_display_program' currently set to '{sdp_value}', " 151 | "override?" 152 | ): 153 | write_autosave = True 154 | else: 155 | echo( 156 | f"{style('WARNING', fg='yellow')}: Manually set " 157 | "'status_display_program' to " 158 | f"'{str(unexpand_sdp_script_path)}'" 159 | ) 160 | if write_autosave: 161 | tmp_autosave_file.write( 162 | f"set status_display_program={str(unexpand_sdp_script_path)}\n" 163 | ) 164 | else: 165 | tmp_autosave_file.write(line) 166 | 167 | # No need to replace 'autosave' if no changes were written 168 | if write_autosave: 169 | rename(tmp_autosave_file.name, cmus_config.autosave_path) 170 | else: 171 | remove(tmp_autosave_file.name) 172 | 173 | if not write_rc and not write_autosave: 174 | echo(f"{style('NOTE', fg='magenta')}: Already installed.") 175 | else: 176 | echo(f"{style('SUCCESS', fg='green')}: Successfully installed.") 177 | 178 | 179 | @entrypoint.command() 180 | @click.pass_context 181 | def uninstall(ctx): 182 | cmus_config = ctx.obj["cmus_config"] 183 | cmus_osx_base_path = ctx.obj["cmus_osx_base_path"] 184 | rc_script_path = ctx.obj["rc_script_path"] 185 | sdp_script_path = ctx.obj["sdp_script_path"] 186 | 187 | try: 188 | rmtree(cmus_osx_base_path) 189 | except FileNotFoundError: 190 | pass 191 | 192 | cmus_instances = get_cmus_instances() 193 | 194 | if cmus_instances is not None: 195 | for pid in cmus_instances: 196 | kill(pid, SIGTERM) 197 | 198 | write_rc = False 199 | 200 | tmp_rc_file = NamedTemporaryFile("w", delete=False) 201 | with open(cmus_config.rc_path, "r") as f: 202 | for line in f: 203 | match = RC_ENTRY_REGEX.match(line) 204 | # Exclude invocations of 'rc' script 205 | if not (match is not None and Path(match.group(1)) == rc_script_path): 206 | tmp_rc_file.write(line) 207 | else: 208 | write_rc = True 209 | 210 | if write_rc: 211 | rename(tmp_rc_file.name, cmus_config.rc_path) 212 | else: 213 | remove(tmp_rc_file.name) 214 | 215 | write_autosave = False 216 | 217 | tmp_autosave_file = NamedTemporaryFile("w", delete=False) 218 | with open(cmus_config.autosave_path, "r") as f: 219 | for line in f: 220 | match = STATUS_DISPLAY_PROGRAM_REGEX.match(line) 221 | # Exclude invocations of 'status_display_program' script 222 | if not (match is not None and Path(match.group(1)) == sdp_script_path): 223 | tmp_autosave_file.write(line) 224 | else: 225 | tmp_autosave_file.write("set status_display_program=\n") 226 | write_autosave = True 227 | 228 | # No need to replace 'autosave' if no changes were written 229 | if write_autosave: 230 | rename(tmp_autosave_file.name, cmus_config.autosave_path) 231 | else: 232 | remove(tmp_autosave_file.name) 233 | 234 | if not write_rc and not write_autosave: 235 | echo(f"{style('NOTE', fg='magenta')}: Already uninstalled.") 236 | else: 237 | echo(f"{style('SUCCESS', fg='green')}: Successfully uninstalled.") 238 | 239 | 240 | @entrypoint.command() 241 | @click.pass_context 242 | def config(ctx): 243 | cmus_osx_base_path = ctx.obj["cmus_osx_base_path"] 244 | 245 | config_path = cmus_osx_base_path / CONFIG_NAME 246 | 247 | editor = locate_editor() 248 | 249 | if editor is None: 250 | echo( 251 | f"{style('ERROR', fg='red')}: Could not locate editor, " 252 | f"manually edit '{str(config_path)}'" 253 | ) 254 | else: 255 | call([str(editor), str(config_path)]) 256 | -------------------------------------------------------------------------------- /cmus_osx/constants.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from re import compile as re_compile 3 | from sys import executable 4 | from sys import modules 5 | from typing import Dict 6 | 7 | from .env import Default 8 | from .util import unexpanduser 9 | 10 | STATUS_DISPLAY_PROGRAM_REGEX = re_compile(r"set status_display_program=(.*)") 11 | RC_ENTRY_REGEX = re_compile(r"shell\s(.*)\s&") 12 | 13 | INTERPRETER_PATH = unexpanduser(Path(executable)) 14 | MODULE_BASE_PATH = Path(modules[__name__].__file__).parent 15 | 16 | RESOURCE_PATH = MODULE_BASE_PATH / "resource" 17 | PAYLOAD_PATH = MODULE_BASE_PATH / "payload" 18 | 19 | APP_ICON_NAME = "icon.png" 20 | RC_SCRIPT_NAME = "rc_entry.sh" 21 | SDP_SCRIPT_NAME = "status_display_program.sh" 22 | 23 | APP_ICON_PATH = unexpanduser(RESOURCE_PATH) / APP_ICON_NAME 24 | 25 | RC_PATH = unexpanduser(PAYLOAD_PATH) / "media_keys.py" 26 | # (s)tatus_(d)isplay_(p)rogram 27 | SDP_PATH = unexpanduser(PAYLOAD_PATH) / "notify.py" 28 | 29 | CMUS_OSX_FOLDER_NAME = "cmus-osx" 30 | CONFIG_NAME = "cmus-osx.conf" 31 | 32 | SCRIPTS: Dict[str, str] = { 33 | RC_SCRIPT_NAME: f"#!/bin/sh\n\nexec {str(INTERPRETER_PATH)} {str(RC_PATH)}", 34 | SDP_SCRIPT_NAME: f'#!/bin/sh\n\nexec {str(INTERPRETER_PATH)} {str(SDP_PATH)} "${{@}}"', 35 | } 36 | 37 | COULD_NOT_LOCATED_CMUS_DIRECTORY = 1 38 | AUTOSAVE_MISSING = 2 39 | 40 | ENV_VAR_PREFIX = "CMUS_OSX" 41 | ENV: Dict[str, Default] = { 42 | "NOTIFICATION_ON_PAUSE": Default( 43 | False, 44 | validator=lambda value: type(value) is bool, 45 | hint="Controls if a notification should be display on pause", 46 | ), 47 | "ITUNES_STYLE_NOTIFICATION": Default( 48 | True, 49 | validator=lambda value: type(value) is bool, 50 | hint="Display album artwork as app icon instead of notification badge", 51 | ), 52 | "APP_ICON": Default( 53 | APP_ICON_PATH, 54 | validator=lambda value: value.expanduser().is_file(), 55 | transformer=lambda value: Path(value), 56 | hint="Fallback icon if album artwork extraction fails", 57 | ), 58 | "THROTTLE_INTERVAL": Default( 59 | 0.0, 60 | validator=lambda value: value >= 0, 61 | hint="Throttle interval (adjust if experiencing duplicated key-pressses)", 62 | ), 63 | } 64 | -------------------------------------------------------------------------------- /cmus_osx/env.py: -------------------------------------------------------------------------------- 1 | from ast import literal_eval 2 | from os import environ 3 | from types import SimpleNamespace 4 | from typing import Any 5 | from typing import Callable 6 | from typing import Dict 7 | from typing import List 8 | from typing import Optional 9 | 10 | from .util import remove_prefix 11 | from .util import safe_execute 12 | 13 | NEWLINE = "\n" 14 | 15 | 16 | class ValidationError(ValueError): 17 | def __init__(self, var_name: str, hint: Optional[str]): 18 | self.var_name = var_name 19 | self.hint = hint 20 | 21 | super().__init__( 22 | f"contents of var '{var_name}' invalid" 23 | f"{f' (hint: {hint})' if hint is not None else ''}" 24 | ) 25 | 26 | 27 | class MissingEnvVarError(ValueError): 28 | def __init__(self, vars_: List[str]): 29 | self.vars_ = vars_ 30 | super().__init__( 31 | f"env variable{'s' if len(vars_) > 1 else ''} missing: {', '.join(vars_)}" 32 | ) 33 | 34 | 35 | class TransformationError(ValueError): 36 | def __init__(self, var_name: str, hint: Optional[str], exception: Exception): 37 | self.var_name = var_name 38 | self.hint = hint 39 | self.exception = exception 40 | 41 | super().__init__( 42 | f"could not transform '{var_name}': {str(exception)} " 43 | f"(hint: {hint if hint is not None else ''})" 44 | ) 45 | 46 | 47 | class InvalidDefault: 48 | pass 49 | 50 | 51 | INVALID_DEFAULT = InvalidDefault() 52 | 53 | 54 | class Default: 55 | def __init__( 56 | self, 57 | value: Any, 58 | validator: Optional[Callable[[Any], bool]] = None, 59 | transformer: Optional[Callable[[Any], Any]] = None, 60 | hint: Optional[str] = None, 61 | ): 62 | self.value = value 63 | self.validator = validator 64 | self.transformer = transformer 65 | self.hint = hint 66 | 67 | def validate(self, value): 68 | return ( 69 | False 70 | if value is INVALID_DEFAULT 71 | else self.validator(value) 72 | if callable(self.validator) 73 | else True 74 | ) 75 | 76 | def transform(self, value): 77 | return self.transformer(value) if callable(self.transformer) else value 78 | 79 | 80 | def check_prefix(env_var_prefix: str) -> str: 81 | return env_var_prefix if env_var_prefix[-1] == "_" else f"{env_var_prefix}_" 82 | 83 | 84 | def template(env_var_prefix: str, defaults: Dict[str, Default]) -> Optional[str]: 85 | template = "" 86 | 87 | env_var_prefix = check_prefix(env_var_prefix) 88 | for name in defaults: 89 | default = defaults[name] 90 | template = ( 91 | f"{template}{f'# {default.hint}{NEWLINE}' if default.hint is not None else ''}" 92 | f"export {env_var_prefix}{name}=" 93 | f"{default.value if default.value not in [None, InvalidDefault] else ''}\n" 94 | ) 95 | 96 | return template 97 | 98 | 99 | def build_env(env_var_prefix: str, defaults: Dict[str, Default]): 100 | # Make sure the environment variable prefix ends with a underscore ('_') 101 | env_var_prefix = check_prefix(env_var_prefix) 102 | env = SimpleNamespace() 103 | 104 | for var in defaults: 105 | value = defaults[var].value 106 | prefix_less = remove_prefix(var, env_var_prefix) 107 | if defaults[prefix_less].validate(value): 108 | # Transformations are not applied for default values 109 | setattr(env, var.lower(), value) 110 | else: 111 | env_var = f"{env_var_prefix}{var}" 112 | # Invalid default might be substituted later 113 | if env_var not in environ: 114 | raise ValidationError(env_var, defaults[prefix_less].hint) 115 | for var in environ: 116 | if var.startswith(env_var_prefix): 117 | prefix_less = remove_prefix(var, env_var_prefix) 118 | if prefix_less in defaults: 119 | # Safely evaluate value 120 | value = safe_execute( 121 | environ[var], 122 | (ValueError, SyntaxError), 123 | lambda: literal_eval(environ[var]), 124 | ) 125 | # Apply transformation 126 | try: 127 | transformed_value = defaults[prefix_less].transform(value) 128 | except Exception as e: 129 | raise TransformationError( 130 | prefix_less, defaults[prefix_less].hint, e 131 | ) 132 | if defaults[prefix_less].validate(transformed_value): 133 | setattr(env, prefix_less.lower(), transformed_value) 134 | else: 135 | raise ValidationError(var, defaults[prefix_less].hint) 136 | else: 137 | # To-Do: User feedback 138 | pass 139 | 140 | missing_vars = [] 141 | 142 | for var in defaults: 143 | if var.lower() not in env.__dict__: 144 | missing_vars.append(var) 145 | 146 | if len(missing_vars) > 0: 147 | raise MissingEnvVarError(missing_vars) 148 | 149 | return env 150 | -------------------------------------------------------------------------------- /cmus_osx/payload/media_keys.py: -------------------------------------------------------------------------------- 1 | from os import _exit as exit 2 | from subprocess import call as call_ 3 | from subprocess import CalledProcessError 4 | from subprocess import check_output 5 | from threading import Thread 6 | from time import sleep 7 | from typing import List 8 | from typing import Optional 9 | 10 | from AppKit import NSApplication 11 | from AppKit import NSApplicationActivationPolicyProhibited 12 | from AppKit import NSKeyUp 13 | from AppKit import NSSystemDefined 14 | from PyObjCTools import AppHelper 15 | 16 | from cmus_osx.constants import CMUS_OSX_FOLDER_NAME 17 | from cmus_osx.constants import CONFIG_NAME 18 | from cmus_osx.constants import ENV 19 | from cmus_osx.constants import ENV_VAR_PREFIX 20 | from cmus_osx.env import build_env 21 | from cmus_osx.util import locate_cmus_base_path 22 | from cmus_osx.util import source_env_file 23 | from cmus_osx.util import throttle 24 | 25 | cmus_base_path = locate_cmus_base_path() 26 | 27 | if cmus_base_path is not None: 28 | source_env_file(cmus_base_path / CMUS_OSX_FOLDER_NAME / CONFIG_NAME) 29 | 30 | # Use defaults values if config file can't be located 31 | env = build_env(ENV_VAR_PREFIX, ENV) 32 | 33 | call = throttle(env.throttle_interval)(call_) 34 | 35 | 36 | class KeySocketApp(NSApplication): 37 | repeated = False 38 | 39 | def sendEvent_(self, event): 40 | if event.type() is NSSystemDefined and event.subtype() == 8: 41 | data = event.data1() 42 | key_code = (data & 0xFFFF0000) >> 16 43 | key_flags = data & 0x0000FFFF 44 | key_state = (key_flags & 0xFF00) >> 8 45 | key_repeat = key_flags & 0x1 46 | 47 | if key_repeat and key_state is not NSKeyUp: 48 | if key_code == 20: 49 | self.repeated = True 50 | call(["cmus-remote", "-k", "-10"]) 51 | elif key_code == 19: 52 | self.repeated = True 53 | call(["cmus-remote", "-k", "+10"]) 54 | 55 | if key_state is NSKeyUp: 56 | if self.repeated: 57 | self.repeated = False 58 | elif key_code in (20, 18): 59 | call(["cmus-remote", "-r"]) 60 | elif key_code == 16: 61 | call(["cmus-remote", "-u"]) 62 | elif key_code in (19, 17): 63 | call(["cmus-remote", "-n"]) 64 | 65 | 66 | class SingleInstanceChecker(Thread): 67 | def __init__(self): 68 | Thread.__init__(self) 69 | self.daemon = True 70 | self.running = False 71 | 72 | def run(self): 73 | self.running = True 74 | while self.running: 75 | cmus_instances = get_cmus_instances() 76 | if cmus_instances is not None: 77 | if len(cmus_instances) == 0: 78 | exit(0) 79 | elif len(cmus_instances) > 1: 80 | call( 81 | [ 82 | "cmus-remote", 83 | "--raw", 84 | "echo Media key support disabled " 85 | "because more than one cmus instance is running.", 86 | ] 87 | ) 88 | exit(1) 89 | else: 90 | call( 91 | [ 92 | "cmus-remote", 93 | "--raw", 94 | "echo Media key support disabled because " 95 | "enumerating cmus instances failed.", 96 | ] 97 | ) 98 | exit(1) 99 | sleep(1) 100 | 101 | def stop(self): 102 | self.running = False 103 | 104 | 105 | def get_cmus_instances() -> Optional[List[int]]: 106 | try: 107 | return [ 108 | int(pid) 109 | for pid in check_output(["pgrep", "-x", "cmus"]).decode().split("\n") 110 | if pid != "" 111 | ] 112 | except CalledProcessError: 113 | return None 114 | 115 | 116 | cmus_instances = get_cmus_instances() 117 | if cmus_instances is not None and len(cmus_instances) == 1: 118 | app = KeySocketApp.sharedApplication() 119 | app.setActivationPolicy_(NSApplicationActivationPolicyProhibited) 120 | single_instance_checker = SingleInstanceChecker() 121 | single_instance_checker.start() 122 | AppHelper.runEventLoop() 123 | else: 124 | exit(1) 125 | -------------------------------------------------------------------------------- /cmus_osx/payload/notify.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from io import BytesIO 3 | from os.path import isfile 4 | from pathlib import Path 5 | from platform import mac_ver 6 | from subprocess import call 7 | 8 | from AppKit import NSBitmapImageRep 9 | from AppKit import NSData 10 | from AppKit import NSImage 11 | from AppKit import NSMakeSize 12 | from Foundation import NSUserNotification 13 | from Foundation import NSUserNotificationCenter 14 | from mutagen import File 15 | from PIL import Image 16 | 17 | from cmus_osx.constants import CMUS_OSX_FOLDER_NAME 18 | from cmus_osx.constants import CONFIG_NAME 19 | from cmus_osx.constants import ENV 20 | from cmus_osx.constants import ENV_VAR_PREFIX 21 | from cmus_osx.env import build_env 22 | from cmus_osx.util import locate_cmus_base_path 23 | from cmus_osx.util import source_env_file 24 | 25 | 26 | def exception_hook(exc_type, exc_value, exc_traceback): 27 | call(["cmus-remote", "--raw", "echo cmus-osx error: %s" % str(exc_value)]) 28 | 29 | 30 | sys.excepthook = exception_hook 31 | 32 | cmus_base_path = locate_cmus_base_path() 33 | 34 | if cmus_base_path is not None: 35 | source_env_file(cmus_base_path / CMUS_OSX_FOLDER_NAME / CONFIG_NAME) 36 | 37 | # Use defaults values if config file can't be located 38 | env = build_env(ENV_VAR_PREFIX, ENV) 39 | 40 | status_raw = sys.argv[1:] 41 | status = dict(zip(status_raw[0::2], status_raw[1::2])) 42 | 43 | # Quickly exit if paused 44 | if "status" in status: 45 | if not env.notification_on_pause: 46 | if status["status"] != "playing": 47 | exit(0) 48 | 49 | cover = None 50 | 51 | if "url" in status: 52 | status["status"] = "(streaming ...)" 53 | # the title may contain both the artist and the song name 54 | if "title" in status: 55 | title_pair = status["title"].split(" - ") 56 | if len(title_pair) > 1: 57 | status["artist"] = title_pair[0] 58 | status["title"] = title_pair[1] 59 | else: 60 | status["title"] = status["url"] 61 | elif "file" in status and isfile(status["file"]): 62 | file = File(status["file"]) 63 | if file is not None: 64 | # id3 65 | if "APIC:" in file: 66 | cover = file["APIC:"] 67 | cover = cover.data 68 | # mp4 69 | elif "covr" in file: 70 | covers = file["covr"] 71 | if len(covers) > 0: 72 | cover = covers[0] 73 | # flac 74 | elif hasattr(file, "pictures") and len(file.pictures) > 0: 75 | cover = file.pictures[0].data 76 | 77 | if env.notification_on_pause: 78 | title = "cmus %s" % status["status"] 79 | else: 80 | title = "cmus" 81 | subtitle = "" 82 | message = "" 83 | 84 | if "tracknumber" in status and status["tracknumber"].isnumeric(): 85 | subtitle += "%s. " % status["tracknumber"] 86 | 87 | if "title" in status: 88 | subtitle += status["title"] 89 | 90 | if "artist" in status: 91 | message += status["artist"] 92 | elif "albumartist" in status: 93 | message += status["albumartist"] 94 | 95 | if "album" in status: 96 | message += " – %s" % status["album"] 97 | 98 | if "date" in status and status["date"].isnumeric(): 99 | message += " (%s)" % status["date"] 100 | 101 | # If no metadata is found, use filename instead 102 | if not subtitle or not message: 103 | filename = Path(status["file"]).name 104 | subtitle = filename 105 | 106 | center = NSUserNotificationCenter.defaultUserNotificationCenter() 107 | notification = NSUserNotification.alloc().init() 108 | 109 | notification.setTitle_(title) 110 | notification.setSubtitle_(subtitle) 111 | notification.setInformativeText_(message) 112 | 113 | # To-Do: Data allocation currently doesn't work in Catalina 114 | if mac_ver()[0] != "10.15": 115 | if cover is not None: # the song has an embedded cover image 116 | data = NSData.alloc().initWithBytes_length_(cover, len(cover)) 117 | image_rep = NSBitmapImageRep.alloc().initWithData_(data) 118 | 119 | # CGImageGetWidth started returning bogus values in macOS 10.14 -> 120 | # Use Pillow to extract the image dimensions 121 | size = NSMakeSize(*Image.open(BytesIO(cover)).size) 122 | 123 | image = NSImage.alloc().initWithSize_(size) 124 | image.addRepresentation_(image_rep) 125 | if env.itunes_style_notification: 126 | 127 | notification.setValue_forKey_(image, "_identityImage") 128 | else: 129 | notification.setValue_forKey_( 130 | NSImage.alloc().initByReferencingFile_(str(env.app_icon)), 131 | "_identityImage", 132 | ) 133 | notification.setContentImage_(image) 134 | else: # song has no cover image, show an icon 135 | notification.setValue_forKey_( 136 | NSImage.alloc().initByReferencingFile_(str(env.app_icon)), "_identityImage" 137 | ) 138 | 139 | center.removeAllDeliveredNotifications() 140 | 141 | center.deliverNotification_(notification) 142 | -------------------------------------------------------------------------------- /cmus_osx/resource/icon.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ba682125e5985e805b77c4ffc088810e08e38129f236a31878396e5858708839 3 | size 851 4 | -------------------------------------------------------------------------------- /cmus_osx/util.py: -------------------------------------------------------------------------------- 1 | from os import environ 2 | from os import getenv 3 | from pathlib import Path 4 | from shutil import which 5 | from subprocess import CalledProcessError 6 | from subprocess import check_output 7 | from subprocess import PIPE 8 | from subprocess import Popen 9 | from time import time 10 | from typing import Any 11 | from typing import Callable 12 | from typing import List 13 | from typing import Optional 14 | from typing import Sequence 15 | from typing import Type 16 | from typing import Union 17 | 18 | 19 | def locate_cmus_base_path() -> Optional[Path]: 20 | for path in ( 21 | path.expanduser() for path in (Path("~/.config/cmus/"), Path("~/.cmus/")) 22 | ): 23 | if path.is_dir(): 24 | return path 25 | return None 26 | 27 | 28 | def locate_editor() -> Optional[Path]: 29 | for editor in (getenv("VISUAL", None), getenv("EDITOR", None), "nano", "vim", "vi"): 30 | if editor is not None: 31 | # Might be absolute path to editor 32 | editor_path = Path(editor).expanduser() 33 | # Might also be just the binary name 34 | editor_which = which(editor) 35 | 36 | if editor_path.is_file(): 37 | return editor_path 38 | elif editor_which is not None: 39 | return Path(editor_which) 40 | return None 41 | 42 | 43 | def safe_execute( 44 | default: Any, 45 | exception: Union[Type[BaseException], Sequence[Type[BaseException]]], 46 | function: Callable, 47 | *args: Any, 48 | **kwargs: Any, 49 | ): 50 | try: 51 | return function(*args, **kwargs) 52 | except exception: # type: ignore 53 | return default 54 | 55 | 56 | def remove_prefix(text: str, prefix: str): 57 | return text[len(prefix) :] if text.startswith(prefix) else text 58 | 59 | 60 | # https://stackoverflow.com/a/3505826 61 | def source_env_file(env_file: Path): 62 | proc = Popen( 63 | ["/bin/sh", "-c", f"set -a && source {str(env_file)} && env"], stdout=PIPE 64 | ) 65 | for line in (line.decode() for line in proc.stdout): 66 | (key, _, value) = line.partition("=") 67 | environ[key] = value.rstrip() 68 | proc.communicate() 69 | 70 | 71 | def get_cmus_instances() -> Optional[List[int]]: 72 | try: 73 | return [ 74 | int(pid) 75 | for pid in check_output(["pgrep", "-x", "cmus"]).decode().split("\n") 76 | if pid != "" 77 | ] 78 | except CalledProcessError: 79 | return None 80 | 81 | 82 | # https://gist.github.com/walkermatt/2871026#gistcomment-2280711 83 | def throttle(interval: Union[float, int]): 84 | """Decorator ensures function that can only be called once every `s` seconds. 85 | """ 86 | 87 | def decorate(fn: Callable) -> Callable: 88 | t = None 89 | 90 | def wrapped(*args, **kwargs): 91 | nonlocal t 92 | t_ = time() 93 | if t is None or t_ - t >= interval: 94 | result = fn(*args, **kwargs) 95 | t = time() 96 | return result 97 | 98 | return wrapped 99 | 100 | return decorate 101 | 102 | 103 | def unexpanduser(path: Path) -> Path: 104 | try: 105 | return Path("~") / path.relative_to(Path.home()) 106 | except ValueError: 107 | return path 108 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | category = "dev" 3 | description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 4 | name = "appdirs" 5 | optional = false 6 | python-versions = "*" 7 | version = "1.4.4" 8 | 9 | [[package]] 10 | category = "dev" 11 | description = "A few extensions to pyyaml." 12 | name = "aspy.yaml" 13 | optional = false 14 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 15 | version = "1.3.0" 16 | 17 | [package.dependencies] 18 | pyyaml = "*" 19 | 20 | [[package]] 21 | category = "dev" 22 | description = "Validate configuration and produce human readable error messages." 23 | name = "cfgv" 24 | optional = false 25 | python-versions = ">=3.6.1" 26 | version = "3.2.0" 27 | 28 | [[package]] 29 | category = "main" 30 | description = "Composable command line interface toolkit" 31 | name = "click" 32 | optional = false 33 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 34 | version = "7.1.2" 35 | 36 | [[package]] 37 | category = "dev" 38 | description = "Distribution utilities" 39 | name = "distlib" 40 | optional = false 41 | python-versions = "*" 42 | version = "0.3.1" 43 | 44 | [[package]] 45 | category = "dev" 46 | description = "A platform independent file lock." 47 | name = "filelock" 48 | optional = false 49 | python-versions = "*" 50 | version = "3.0.12" 51 | 52 | [[package]] 53 | category = "dev" 54 | description = "File identification library for Python" 55 | name = "identify" 56 | optional = false 57 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 58 | version = "1.5.9" 59 | 60 | [package.extras] 61 | license = ["editdistance"] 62 | 63 | [[package]] 64 | category = "dev" 65 | description = "Read metadata from Python packages" 66 | marker = "python_version < \"3.8\"" 67 | name = "importlib-metadata" 68 | optional = false 69 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 70 | version = "2.0.0" 71 | 72 | [package.dependencies] 73 | zipp = ">=0.5" 74 | 75 | [package.extras] 76 | docs = ["sphinx", "rst.linker"] 77 | testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] 78 | 79 | [[package]] 80 | category = "main" 81 | description = "read and write audio tags for many formats" 82 | name = "mutagen" 83 | optional = false 84 | python-versions = ">=3.5, <4" 85 | version = "1.45.1" 86 | 87 | [[package]] 88 | category = "dev" 89 | description = "Node.js virtual environment builder" 90 | name = "nodeenv" 91 | optional = false 92 | python-versions = "*" 93 | version = "1.5.0" 94 | 95 | [[package]] 96 | category = "main" 97 | description = "Python Imaging Library (Fork)" 98 | name = "pillow" 99 | optional = false 100 | python-versions = ">=3.6" 101 | version = "8.0.1" 102 | 103 | [[package]] 104 | category = "dev" 105 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 106 | name = "pre-commit" 107 | optional = false 108 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 109 | version = "1.21.0" 110 | 111 | [package.dependencies] 112 | "aspy.yaml" = "*" 113 | cfgv = ">=2.0.0" 114 | identify = ">=1.0.0" 115 | nodeenv = ">=0.11.1" 116 | pyyaml = "*" 117 | six = "*" 118 | toml = "*" 119 | virtualenv = ">=15.2" 120 | 121 | [package.dependencies.importlib-metadata] 122 | python = "<3.8" 123 | version = "*" 124 | 125 | [[package]] 126 | category = "main" 127 | description = "Python<->ObjC Interoperability Module" 128 | name = "pyobjc" 129 | optional = false 130 | python-versions = ">=3.6" 131 | version = "6.2.2" 132 | 133 | [package.dependencies] 134 | pyobjc-core = "6.2.2" 135 | pyobjc-framework-AVFoundation = "6.2.2" 136 | pyobjc-framework-AVKit = "6.2.2" 137 | pyobjc-framework-Accounts = "6.2.2" 138 | pyobjc-framework-AdSupport = "6.2.2" 139 | pyobjc-framework-AddressBook = "6.2.2" 140 | pyobjc-framework-AppleScriptKit = "6.2.2" 141 | pyobjc-framework-AppleScriptObjC = "6.2.2" 142 | pyobjc-framework-ApplicationServices = "6.2.2" 143 | pyobjc-framework-AuthenticationServices = "6.2.2" 144 | pyobjc-framework-AutomaticAssessmentConfiguration = "6.2.2" 145 | pyobjc-framework-Automator = "6.2.2" 146 | pyobjc-framework-BusinessChat = "6.2.2" 147 | pyobjc-framework-CFNetwork = "6.2.2" 148 | pyobjc-framework-CalendarStore = "6.2.2" 149 | pyobjc-framework-CloudKit = "6.2.2" 150 | pyobjc-framework-Cocoa = "6.2.2" 151 | pyobjc-framework-Collaboration = "6.2.2" 152 | pyobjc-framework-ColorSync = "6.2.2" 153 | pyobjc-framework-Contacts = "6.2.2" 154 | pyobjc-framework-ContactsUI = "6.2.2" 155 | pyobjc-framework-CoreAudio = "6.2.2" 156 | pyobjc-framework-CoreAudioKit = "6.2.2" 157 | pyobjc-framework-CoreBluetooth = "6.2.2" 158 | pyobjc-framework-CoreData = "6.2.2" 159 | pyobjc-framework-CoreHaptics = "6.2.2" 160 | pyobjc-framework-CoreLocation = "6.2.2" 161 | pyobjc-framework-CoreML = "6.2.2" 162 | pyobjc-framework-CoreMedia = "6.2.2" 163 | pyobjc-framework-CoreMediaIO = "6.2.2" 164 | pyobjc-framework-CoreMotion = "6.2.2" 165 | pyobjc-framework-CoreServices = "6.2.2" 166 | pyobjc-framework-CoreSpotlight = "6.2.2" 167 | pyobjc-framework-CoreText = "6.2.2" 168 | pyobjc-framework-CoreWLAN = "6.2.2" 169 | pyobjc-framework-CryptoTokenKit = "6.2.2" 170 | pyobjc-framework-DVDPlayback = "6.2.2" 171 | pyobjc-framework-DeviceCheck = "6.2.2" 172 | pyobjc-framework-DictionaryServices = "6.2.2" 173 | pyobjc-framework-DiscRecording = "6.2.2" 174 | pyobjc-framework-DiscRecordingUI = "6.2.2" 175 | pyobjc-framework-DiskArbitration = "6.2.2" 176 | pyobjc-framework-EventKit = "6.2.2" 177 | pyobjc-framework-ExceptionHandling = "6.2.2" 178 | pyobjc-framework-ExecutionPolicy = "6.2.2" 179 | pyobjc-framework-ExternalAccessory = "6.2.2" 180 | pyobjc-framework-FSEvents = "6.2.2" 181 | pyobjc-framework-FileProvider = "6.2.2" 182 | pyobjc-framework-FileProviderUI = "6.2.2" 183 | pyobjc-framework-FinderSync = "6.2.2" 184 | pyobjc-framework-GameCenter = "6.2.2" 185 | pyobjc-framework-GameController = "6.2.2" 186 | pyobjc-framework-GameKit = "6.2.2" 187 | pyobjc-framework-GameplayKit = "6.2.2" 188 | pyobjc-framework-IMServicePlugIn = "6.2.2" 189 | pyobjc-framework-IOSurface = "6.2.2" 190 | pyobjc-framework-ImageCaptureCore = "6.2.2" 191 | pyobjc-framework-InputMethodKit = "6.2.2" 192 | pyobjc-framework-InstallerPlugins = "6.2.2" 193 | pyobjc-framework-InstantMessage = "6.2.2" 194 | pyobjc-framework-Intents = "6.2.2" 195 | pyobjc-framework-InterfaceBuilderKit = "6.2.2" 196 | pyobjc-framework-LatentSemanticMapping = "6.2.2" 197 | pyobjc-framework-LaunchServices = "6.2.2" 198 | pyobjc-framework-LinkPresentation = "6.2.2" 199 | pyobjc-framework-LocalAuthentication = "6.2.2" 200 | pyobjc-framework-MapKit = "6.2.2" 201 | pyobjc-framework-MediaAccessibility = "6.2.2" 202 | pyobjc-framework-MediaLibrary = "6.2.2" 203 | pyobjc-framework-MediaPlayer = "6.2.2" 204 | pyobjc-framework-MediaToolbox = "6.2.2" 205 | pyobjc-framework-Message = "6.2.2" 206 | pyobjc-framework-Metal = "6.2.2" 207 | pyobjc-framework-MetalKit = "6.2.2" 208 | pyobjc-framework-ModelIO = "6.2.2" 209 | pyobjc-framework-MultipeerConnectivity = "6.2.2" 210 | pyobjc-framework-NaturalLanguage = "6.2.2" 211 | pyobjc-framework-NetFS = "6.2.2" 212 | pyobjc-framework-Network = "6.2.2" 213 | pyobjc-framework-NetworkExtension = "6.2.2" 214 | pyobjc-framework-NotificationCenter = "6.2.2" 215 | pyobjc-framework-OSAKit = "6.2.2" 216 | pyobjc-framework-OSLog = "6.2.2" 217 | pyobjc-framework-OpenDirectory = "6.2.2" 218 | pyobjc-framework-PencilKit = "6.2.2" 219 | pyobjc-framework-Photos = "6.2.2" 220 | pyobjc-framework-PhotosUI = "6.2.2" 221 | pyobjc-framework-PreferencePanes = "6.2.2" 222 | pyobjc-framework-PubSub = "6.2.2" 223 | pyobjc-framework-PushKit = "6.2.2" 224 | pyobjc-framework-QTKit = "6.2.2" 225 | pyobjc-framework-Quartz = "6.2.2" 226 | pyobjc-framework-QuickLookThumbnailing = "6.2.2" 227 | pyobjc-framework-SafariServices = "6.2.2" 228 | pyobjc-framework-SceneKit = "6.2.2" 229 | pyobjc-framework-ScreenSaver = "6.2.2" 230 | pyobjc-framework-ScriptingBridge = "6.2.2" 231 | pyobjc-framework-SearchKit = "6.2.2" 232 | pyobjc-framework-Security = "6.2.2" 233 | pyobjc-framework-SecurityFoundation = "6.2.2" 234 | pyobjc-framework-SecurityInterface = "6.2.2" 235 | pyobjc-framework-ServerNotification = "6.2.2" 236 | pyobjc-framework-ServiceManagement = "6.2.2" 237 | pyobjc-framework-Social = "6.2.2" 238 | pyobjc-framework-SoundAnalysis = "6.2.2" 239 | pyobjc-framework-Speech = "6.2.2" 240 | pyobjc-framework-SpriteKit = "6.2.2" 241 | pyobjc-framework-StoreKit = "6.2.2" 242 | pyobjc-framework-SyncServices = "6.2.2" 243 | pyobjc-framework-SystemConfiguration = "6.2.2" 244 | pyobjc-framework-SystemExtensions = "6.2.2" 245 | pyobjc-framework-UserNotifications = "6.2.2" 246 | pyobjc-framework-VideoSubscriberAccount = "6.2.2" 247 | pyobjc-framework-VideoToolbox = "6.2.2" 248 | pyobjc-framework-Vision = "6.2.2" 249 | pyobjc-framework-WebKit = "6.2.2" 250 | pyobjc-framework-XgridFoundation = "6.2.2" 251 | pyobjc-framework-iTunesLibrary = "6.2.2" 252 | pyobjc-framework-libdispatch = "6.2.2" 253 | 254 | [[package]] 255 | category = "main" 256 | description = "Python<->ObjC Interoperability Module" 257 | name = "pyobjc-core" 258 | optional = false 259 | python-versions = ">=3.6" 260 | version = "6.2.2" 261 | 262 | [[package]] 263 | category = "main" 264 | description = "Wrappers for the framework Accounts on macOS" 265 | marker = "platform_release >= \"12.0\" or platform_release >= \"14.0\"" 266 | name = "pyobjc-framework-accounts" 267 | optional = false 268 | python-versions = ">=3.6" 269 | version = "6.2.2" 270 | 271 | [package.dependencies] 272 | pyobjc-core = ">=6.2.2" 273 | pyobjc-framework-Cocoa = ">=6.2.2" 274 | 275 | [[package]] 276 | category = "main" 277 | description = "Wrappers for the framework AddressBook on macOS" 278 | name = "pyobjc-framework-addressbook" 279 | optional = false 280 | python-versions = ">=3.6" 281 | version = "6.2.2" 282 | 283 | [package.dependencies] 284 | pyobjc-core = ">=6.2.2" 285 | pyobjc-framework-Cocoa = ">=6.2.2" 286 | 287 | [[package]] 288 | category = "main" 289 | description = "Wrappers for the framework AdSupport on macOS" 290 | marker = "platform_release >= \"18.0\"" 291 | name = "pyobjc-framework-adsupport" 292 | optional = false 293 | python-versions = ">=3.6" 294 | version = "6.2.2" 295 | 296 | [package.dependencies] 297 | pyobjc-core = ">=6.2.2" 298 | pyobjc-framework-Cocoa = ">=6.2.2" 299 | 300 | [[package]] 301 | category = "main" 302 | description = "Wrappers for the framework AppleScriptKit on macOS" 303 | name = "pyobjc-framework-applescriptkit" 304 | optional = false 305 | python-versions = ">=3.6" 306 | version = "6.2.2" 307 | 308 | [package.dependencies] 309 | pyobjc-core = ">=6.2.2" 310 | pyobjc-framework-Cocoa = ">=6.2.2" 311 | 312 | [[package]] 313 | category = "main" 314 | description = "Wrappers for the framework AppleScriptObjC on macOS" 315 | marker = "platform_release >= \"10.0\"" 316 | name = "pyobjc-framework-applescriptobjc" 317 | optional = false 318 | python-versions = ">=3.6" 319 | version = "6.2.2" 320 | 321 | [package.dependencies] 322 | pyobjc-core = ">=6.2.2" 323 | pyobjc-framework-Cocoa = ">=6.2.2" 324 | 325 | [[package]] 326 | category = "main" 327 | description = "Wrappers for the framework ApplicationServices on macOS" 328 | name = "pyobjc-framework-applicationservices" 329 | optional = false 330 | python-versions = ">=3.6" 331 | version = "6.2.2" 332 | 333 | [package.dependencies] 334 | pyobjc-core = ">=6.2.2" 335 | pyobjc-framework-Cocoa = ">=6.2.2" 336 | pyobjc-framework-Quartz = ">=6.2.2" 337 | 338 | [[package]] 339 | category = "main" 340 | description = "Wrappers for the framework AuthenticationServices on macOS" 341 | marker = "platform_release >= \"19.0\"" 342 | name = "pyobjc-framework-authenticationservices" 343 | optional = false 344 | python-versions = ">=3.6" 345 | version = "6.2.2" 346 | 347 | [package.dependencies] 348 | pyobjc-core = ">=6.2.2" 349 | pyobjc-framework-Cocoa = ">=6.2.2" 350 | 351 | [[package]] 352 | category = "main" 353 | description = "Wrappers for the framework AutomaticAssessmentConfiguration on macOS" 354 | marker = "platform_release >= \"19.0\"" 355 | name = "pyobjc-framework-automaticassessmentconfiguration" 356 | optional = false 357 | python-versions = ">=3.6" 358 | version = "6.2.2" 359 | 360 | [package.dependencies] 361 | pyobjc-core = ">=6.2.2" 362 | pyobjc-framework-Cocoa = ">=6.2.2" 363 | 364 | [[package]] 365 | category = "main" 366 | description = "Wrappers for the framework Automator on macOS" 367 | name = "pyobjc-framework-automator" 368 | optional = false 369 | python-versions = ">=3.6" 370 | version = "6.2.2" 371 | 372 | [package.dependencies] 373 | pyobjc-core = ">=6.2.2" 374 | pyobjc-framework-Cocoa = ">=6.2.2" 375 | 376 | [[package]] 377 | category = "main" 378 | description = "Wrappers for the framework AVFoundation on macOS" 379 | marker = "platform_release >= \"11.0\" or platform_release >= \"16.0\"" 380 | name = "pyobjc-framework-avfoundation" 381 | optional = false 382 | python-versions = ">=3.6" 383 | version = "6.2.2" 384 | 385 | [package.dependencies] 386 | pyobjc-core = ">=6.2.2" 387 | pyobjc-framework-Cocoa = ">=6.2.2" 388 | pyobjc-framework-CoreMedia = ">=6.2.2" 389 | pyobjc-framework-Quartz = ">=6.2.2" 390 | 391 | [[package]] 392 | category = "main" 393 | description = "Wrappers for the framework AVKit on macOS" 394 | marker = "platform_release >= \"13.0\"" 395 | name = "pyobjc-framework-avkit" 396 | optional = false 397 | python-versions = ">=3.6" 398 | version = "6.2.2" 399 | 400 | [package.dependencies] 401 | pyobjc-core = ">=6.2.2" 402 | pyobjc-framework-Cocoa = ">=6.2.2" 403 | pyobjc-framework-Quartz = ">=6.2.2" 404 | 405 | [[package]] 406 | category = "main" 407 | description = "Wrappers for the framework BusinessChat on macOS" 408 | marker = "platform_release >= \"18.0\"" 409 | name = "pyobjc-framework-businesschat" 410 | optional = false 411 | python-versions = ">=3.6" 412 | version = "6.2.2" 413 | 414 | [package.dependencies] 415 | pyobjc-core = ">=6.2.2" 416 | pyobjc-framework-Cocoa = ">=6.2.2" 417 | 418 | [[package]] 419 | category = "main" 420 | description = "Wrappers for the framework CalendarStore on macOS" 421 | marker = "platform_release >= \"9.0\"" 422 | name = "pyobjc-framework-calendarstore" 423 | optional = false 424 | python-versions = ">=3.6" 425 | version = "6.2.2" 426 | 427 | [package.dependencies] 428 | pyobjc-core = ">=6.2.2" 429 | pyobjc-framework-Cocoa = ">=6.2.2" 430 | 431 | [[package]] 432 | category = "main" 433 | description = "Wrappers for the framework CFNetwork on macOS" 434 | name = "pyobjc-framework-cfnetwork" 435 | optional = false 436 | python-versions = ">=3.6" 437 | version = "6.2.2" 438 | 439 | [package.dependencies] 440 | pyobjc-core = ">=6.2.2" 441 | pyobjc-framework-Cocoa = ">=6.2.2" 442 | 443 | [[package]] 444 | category = "main" 445 | description = "Wrappers for the framework CloudKit on macOS" 446 | marker = "platform_release >= \"14.0\"" 447 | name = "pyobjc-framework-cloudkit" 448 | optional = false 449 | python-versions = ">=3.6" 450 | version = "6.2.2" 451 | 452 | [package.dependencies] 453 | pyobjc-core = ">=6.2.2" 454 | pyobjc-framework-Accounts = ">=6.2.2" 455 | pyobjc-framework-Cocoa = ">=6.2.2" 456 | pyobjc-framework-CoreData = ">=6.2.2" 457 | pyobjc-framework-CoreLocation = ">=6.2.2" 458 | 459 | [[package]] 460 | category = "main" 461 | description = "Wrappers for the Cocoa frameworks on macOS" 462 | name = "pyobjc-framework-cocoa" 463 | optional = false 464 | python-versions = ">=3.6" 465 | version = "6.2.2" 466 | 467 | [package.dependencies] 468 | pyobjc-core = ">=6.2.2" 469 | 470 | [[package]] 471 | category = "main" 472 | description = "Wrappers for the framework Collaboration on macOS" 473 | marker = "platform_release >= \"9.0\"" 474 | name = "pyobjc-framework-collaboration" 475 | optional = false 476 | python-versions = ">=3.6" 477 | version = "6.2.2" 478 | 479 | [package.dependencies] 480 | pyobjc-core = ">=6.2.2" 481 | pyobjc-framework-Cocoa = ">=6.2.2" 482 | 483 | [[package]] 484 | category = "main" 485 | description = "Wrappers for the framework ColorSync on Mac OS X" 486 | marker = "platform_release >= \"17.0\"" 487 | name = "pyobjc-framework-colorsync" 488 | optional = false 489 | python-versions = ">=3.6" 490 | version = "6.2.2" 491 | 492 | [package.dependencies] 493 | pyobjc-core = ">=6.2.2" 494 | pyobjc-framework-Cocoa = ">=6.2.2" 495 | 496 | [[package]] 497 | category = "main" 498 | description = "Wrappers for the framework Contacts on macOS" 499 | marker = "platform_release >= \"15.0\"" 500 | name = "pyobjc-framework-contacts" 501 | optional = false 502 | python-versions = ">=3.6" 503 | version = "6.2.2" 504 | 505 | [package.dependencies] 506 | pyobjc-core = ">=6.2.2" 507 | pyobjc-framework-Cocoa = ">=6.2.2" 508 | 509 | [[package]] 510 | category = "main" 511 | description = "Wrappers for the framework ContactsUI on macOS" 512 | marker = "platform_release >= \"15.0\"" 513 | name = "pyobjc-framework-contactsui" 514 | optional = false 515 | python-versions = ">=3.6" 516 | version = "6.2.2" 517 | 518 | [package.dependencies] 519 | pyobjc-core = ">=6.2.2" 520 | pyobjc-framework-Cocoa = ">=6.2.2" 521 | pyobjc-framework-Contacts = ">=6.2.2" 522 | 523 | [[package]] 524 | category = "main" 525 | description = "Wrappers for the framework CoreAudio on macOS" 526 | name = "pyobjc-framework-coreaudio" 527 | optional = false 528 | python-versions = ">=3.6" 529 | version = "6.2.2" 530 | 531 | [package.dependencies] 532 | pyobjc-core = ">=6.2.2" 533 | pyobjc-framework-Cocoa = ">=6.2.2" 534 | 535 | [[package]] 536 | category = "main" 537 | description = "Wrappers for the framework CoreAudioKit on macOS" 538 | name = "pyobjc-framework-coreaudiokit" 539 | optional = false 540 | python-versions = ">=3.6" 541 | version = "6.2.2" 542 | 543 | [package.dependencies] 544 | pyobjc-core = ">=6.2.2" 545 | pyobjc-framework-Cocoa = ">=6.2.2" 546 | pyobjc-framework-CoreAudio = ">=6.2.2" 547 | 548 | [[package]] 549 | category = "main" 550 | description = "Wrappers for the framework CoreBluetooth on macOS" 551 | marker = "platform_release >= \"14.0\"" 552 | name = "pyobjc-framework-corebluetooth" 553 | optional = false 554 | python-versions = ">=3.6" 555 | version = "6.2.2" 556 | 557 | [package.dependencies] 558 | pyobjc-core = ">=6.2.2" 559 | pyobjc-framework-Cocoa = ">=6.2.2" 560 | 561 | [[package]] 562 | category = "main" 563 | description = "Wrappers for the framework CoreData on macOS" 564 | name = "pyobjc-framework-coredata" 565 | optional = false 566 | python-versions = ">=3.6" 567 | version = "6.2.2" 568 | 569 | [package.dependencies] 570 | pyobjc-core = ">=6.2.2" 571 | pyobjc-framework-Cocoa = ">=6.2.2" 572 | 573 | [[package]] 574 | category = "main" 575 | description = "Wrappers for the framework CoreHaptics on macOS" 576 | marker = "platform_release >= \"19.0\"" 577 | name = "pyobjc-framework-corehaptics" 578 | optional = false 579 | python-versions = ">=3.6" 580 | version = "6.2.2" 581 | 582 | [package.dependencies] 583 | pyobjc-core = ">=6.2.2" 584 | pyobjc-framework-Cocoa = ">=6.2.2" 585 | 586 | [[package]] 587 | category = "main" 588 | description = "Wrappers for the framework CoreLocation on macOS" 589 | marker = "platform_release >= \"10.0\" or platform_release >= \"13.0\" or platform_release >= \"14.0\"" 590 | name = "pyobjc-framework-corelocation" 591 | optional = false 592 | python-versions = ">=3.6" 593 | version = "6.2.2" 594 | 595 | [package.dependencies] 596 | pyobjc-core = ">=6.2.2" 597 | pyobjc-framework-Cocoa = ">=6.2.2" 598 | 599 | [[package]] 600 | category = "main" 601 | description = "Wrappers for the framework CoreMedia on macOS" 602 | marker = "platform_release >= \"11.0\" or platform_release >= \"12.0\" or platform_release >= \"16.0\" or platform_release >= \"19.0\"" 603 | name = "pyobjc-framework-coremedia" 604 | optional = false 605 | python-versions = ">=3.6" 606 | version = "6.2.2" 607 | 608 | [package.dependencies] 609 | pyobjc-core = ">=6.2.2" 610 | pyobjc-framework-Cocoa = ">=6.2.2" 611 | 612 | [[package]] 613 | category = "main" 614 | description = "Wrappers for the framework CoreMediaIO on macOS" 615 | marker = "platform_release >= \"11.0\"" 616 | name = "pyobjc-framework-coremediaio" 617 | optional = false 618 | python-versions = ">=3.6" 619 | version = "6.2.2" 620 | 621 | [package.dependencies] 622 | pyobjc-core = ">=6.2.2" 623 | pyobjc-framework-Cocoa = ">=6.2.2" 624 | 625 | [[package]] 626 | category = "main" 627 | description = "Wrappers for the framework CoreML on macOS" 628 | marker = "platform_release >= \"17.0\"" 629 | name = "pyobjc-framework-coreml" 630 | optional = false 631 | python-versions = ">=3.6" 632 | version = "6.2.2" 633 | 634 | [package.dependencies] 635 | pyobjc-core = ">=6.2.2" 636 | pyobjc-framework-Cocoa = ">=6.2.2" 637 | 638 | [[package]] 639 | category = "main" 640 | description = "Wrappers for the framework CoreMotion on macOS" 641 | marker = "platform_release >= \"19.0\"" 642 | name = "pyobjc-framework-coremotion" 643 | optional = false 644 | python-versions = ">=3.6" 645 | version = "6.2.2" 646 | 647 | [package.dependencies] 648 | pyobjc-core = ">=6.2.2" 649 | pyobjc-framework-Cocoa = ">=6.2.2" 650 | 651 | [[package]] 652 | category = "main" 653 | description = "Wrappers for the framework CoreServices on macOS" 654 | name = "pyobjc-framework-coreservices" 655 | optional = false 656 | python-versions = ">=3.6" 657 | version = "6.2.2" 658 | 659 | [package.dependencies] 660 | pyobjc-core = ">=6.2.2" 661 | pyobjc-framework-FSEvents = ">=6.2.2" 662 | 663 | [[package]] 664 | category = "main" 665 | description = "Wrappers for the framework CoreSpotlight on macOS" 666 | marker = "platform_release >= \"17.0\"" 667 | name = "pyobjc-framework-corespotlight" 668 | optional = false 669 | python-versions = ">=3.6" 670 | version = "6.2.2" 671 | 672 | [package.dependencies] 673 | pyobjc-core = ">=6.2.2" 674 | pyobjc-framework-Cocoa = ">=6.2.2" 675 | 676 | [[package]] 677 | category = "main" 678 | description = "Wrappers for the framework CoreText on macOS" 679 | name = "pyobjc-framework-coretext" 680 | optional = false 681 | python-versions = ">=3.6" 682 | version = "6.2.2" 683 | 684 | [package.dependencies] 685 | pyobjc-core = ">=6.2.2" 686 | pyobjc-framework-Cocoa = ">=6.2.2" 687 | pyobjc-framework-Quartz = ">=6.2.2" 688 | 689 | [[package]] 690 | category = "main" 691 | description = "Wrappers for the framework CoreWLAN on macOS" 692 | marker = "platform_release >= \"10.0\"" 693 | name = "pyobjc-framework-corewlan" 694 | optional = false 695 | python-versions = ">=3.6" 696 | version = "6.2.2" 697 | 698 | [package.dependencies] 699 | pyobjc-core = ">=6.2.2" 700 | pyobjc-framework-Cocoa = ">=6.2.2" 701 | 702 | [[package]] 703 | category = "main" 704 | description = "Wrappers for the framework CryptoTokenKit on macOS" 705 | marker = "platform_release >= \"14.0\"" 706 | name = "pyobjc-framework-cryptotokenkit" 707 | optional = false 708 | python-versions = ">=3.6" 709 | version = "6.2.2" 710 | 711 | [package.dependencies] 712 | pyobjc-core = ">=6.2.2" 713 | pyobjc-framework-Cocoa = ">=6.2.2" 714 | 715 | [[package]] 716 | category = "main" 717 | description = "Wrappers for the framework DeviceCheck on macOS" 718 | marker = "platform_release >= \"19.0\"" 719 | name = "pyobjc-framework-devicecheck" 720 | optional = false 721 | python-versions = ">=3.6" 722 | version = "6.2.2" 723 | 724 | [package.dependencies] 725 | pyobjc-core = ">=6.2.2" 726 | pyobjc-framework-Cocoa = ">=6.2.2" 727 | 728 | [[package]] 729 | category = "main" 730 | description = "Wrappers for the framework DictionaryServices on macOS" 731 | marker = "platform_release >= \"9.0\"" 732 | name = "pyobjc-framework-dictionaryservices" 733 | optional = false 734 | python-versions = ">=3.6" 735 | version = "6.2.2" 736 | 737 | [package.dependencies] 738 | pyobjc-core = ">=6.2.2" 739 | pyobjc-framework-CoreServices = ">=6.2.2" 740 | 741 | [[package]] 742 | category = "main" 743 | description = "Wrappers for the framework DiscRecording on macOS" 744 | name = "pyobjc-framework-discrecording" 745 | optional = false 746 | python-versions = ">=3.6" 747 | version = "6.2.2" 748 | 749 | [package.dependencies] 750 | pyobjc-core = ">=6.2.2" 751 | pyobjc-framework-Cocoa = ">=6.2.2" 752 | 753 | [[package]] 754 | category = "main" 755 | description = "Wrappers for the framework DiscRecordingUI on macOS" 756 | name = "pyobjc-framework-discrecordingui" 757 | optional = false 758 | python-versions = ">=3.6" 759 | version = "6.2.2" 760 | 761 | [package.dependencies] 762 | pyobjc-core = ">=6.2.2" 763 | pyobjc-framework-Cocoa = ">=6.2.2" 764 | pyobjc-framework-DiscRecording = ">=6.2.2" 765 | 766 | [[package]] 767 | category = "main" 768 | description = "Wrappers for the framework DiskArbitration on macOS" 769 | name = "pyobjc-framework-diskarbitration" 770 | optional = false 771 | python-versions = ">=3.6" 772 | version = "6.2.2" 773 | 774 | [package.dependencies] 775 | pyobjc-core = ">=6.2.2" 776 | pyobjc-framework-Cocoa = ">=6.2.2" 777 | 778 | [[package]] 779 | category = "main" 780 | description = "Wrappers for the framework DVDPlayback on macOS" 781 | name = "pyobjc-framework-dvdplayback" 782 | optional = false 783 | python-versions = ">=3.6" 784 | version = "6.2.2" 785 | 786 | [package.dependencies] 787 | pyobjc-core = ">=6.2.2" 788 | pyobjc-framework-Cocoa = ">=6.2.2" 789 | 790 | [[package]] 791 | category = "main" 792 | description = "Wrappers for the framework Accounts on macOS" 793 | marker = "platform_release >= \"12.0\"" 794 | name = "pyobjc-framework-eventkit" 795 | optional = false 796 | python-versions = ">=3.6" 797 | version = "6.2.2" 798 | 799 | [package.dependencies] 800 | pyobjc-core = ">=6.2.2" 801 | pyobjc-framework-Cocoa = ">=6.2.2" 802 | 803 | [[package]] 804 | category = "main" 805 | description = "Wrappers for the framework ExceptionHandling on macOS" 806 | name = "pyobjc-framework-exceptionhandling" 807 | optional = false 808 | python-versions = ">=3.6" 809 | version = "6.2.2" 810 | 811 | [package.dependencies] 812 | pyobjc-core = ">=6.2.2" 813 | pyobjc-framework-Cocoa = ">=6.2.2" 814 | 815 | [[package]] 816 | category = "main" 817 | description = "Wrappers for the framework ExecutionPolicy on macOS" 818 | marker = "platform_release >= \"19.0\"" 819 | name = "pyobjc-framework-executionpolicy" 820 | optional = false 821 | python-versions = ">=3.6" 822 | version = "6.2.2" 823 | 824 | [package.dependencies] 825 | pyobjc-core = ">=6.2.2" 826 | pyobjc-framework-Cocoa = ">=6.2.2" 827 | 828 | [[package]] 829 | category = "main" 830 | description = "Wrappers for the framework ExternalAccessory on macOS" 831 | marker = "platform_release >= \"17.0\"" 832 | name = "pyobjc-framework-externalaccessory" 833 | optional = false 834 | python-versions = ">=3.6" 835 | version = "6.2.2" 836 | 837 | [package.dependencies] 838 | pyobjc-core = ">=6.2.2" 839 | pyobjc-framework-Cocoa = ">=6.2.2" 840 | 841 | [[package]] 842 | category = "main" 843 | description = "Wrappers for the framework FileProvider on macOS" 844 | marker = "platform_release >= \"19.0\"" 845 | name = "pyobjc-framework-fileprovider" 846 | optional = false 847 | python-versions = ">=3.6" 848 | version = "6.2.2" 849 | 850 | [package.dependencies] 851 | pyobjc-core = ">=6.2.2" 852 | pyobjc-framework-Cocoa = ">=6.2.2" 853 | 854 | [[package]] 855 | category = "main" 856 | description = "Wrappers for the framework FileProviderUI on macOS" 857 | marker = "platform_release >= \"19.0\"" 858 | name = "pyobjc-framework-fileproviderui" 859 | optional = false 860 | python-versions = ">=3.6" 861 | version = "6.2.2" 862 | 863 | [package.dependencies] 864 | pyobjc-core = ">=6.2.2" 865 | pyobjc-framework-FileProvider = ">=6.2.2" 866 | 867 | [[package]] 868 | category = "main" 869 | description = "Wrappers for the framework FinderSync on macOS" 870 | marker = "platform_release >= \"14.0\"" 871 | name = "pyobjc-framework-findersync" 872 | optional = false 873 | python-versions = ">=3.6" 874 | version = "6.2.2" 875 | 876 | [package.dependencies] 877 | pyobjc-core = ">=6.2.2" 878 | pyobjc-framework-Cocoa = ">=6.2.2" 879 | 880 | [[package]] 881 | category = "main" 882 | description = "Wrappers for the framework FSEvents on macOS" 883 | name = "pyobjc-framework-fsevents" 884 | optional = false 885 | python-versions = ">=3.6" 886 | version = "6.2.2" 887 | 888 | [package.dependencies] 889 | pyobjc-core = ">=6.2.2" 890 | pyobjc-framework-Cocoa = ">=6.2.2" 891 | 892 | [[package]] 893 | category = "main" 894 | description = "Wrappers for the framework GameCenter on macOS" 895 | marker = "platform_release >= \"12.0\"" 896 | name = "pyobjc-framework-gamecenter" 897 | optional = false 898 | python-versions = ">=3.6" 899 | version = "6.2.2" 900 | 901 | [package.dependencies] 902 | pyobjc-core = ">=6.2.2" 903 | pyobjc-framework-Cocoa = ">=6.2.2" 904 | 905 | [[package]] 906 | category = "main" 907 | description = "Wrappers for the framework GameController on macOS" 908 | marker = "platform_release >= \"13.0\"" 909 | name = "pyobjc-framework-gamecontroller" 910 | optional = false 911 | python-versions = ">=3.6" 912 | version = "6.2.2" 913 | 914 | [package.dependencies] 915 | pyobjc-core = ">=6.2.2" 916 | pyobjc-framework-Cocoa = ">=6.2.2" 917 | 918 | [[package]] 919 | category = "main" 920 | description = "Wrappers for the framework GameKit on macOS" 921 | marker = "platform_release >= \"12.0\"" 922 | name = "pyobjc-framework-gamekit" 923 | optional = false 924 | python-versions = ">=3.6" 925 | version = "6.2.2" 926 | 927 | [package.dependencies] 928 | pyobjc-core = ">=6.2.2" 929 | pyobjc-framework-Cocoa = ">=6.2.2" 930 | pyobjc-framework-Quartz = ">=6.2.2" 931 | 932 | [[package]] 933 | category = "main" 934 | description = "Wrappers for the framework GameplayKit on macOS" 935 | marker = "platform_release >= \"15.0\"" 936 | name = "pyobjc-framework-gameplaykit" 937 | optional = false 938 | python-versions = ">=3.6" 939 | version = "6.2.2" 940 | 941 | [package.dependencies] 942 | pyobjc-core = ">=6.2.2" 943 | pyobjc-framework-Cocoa = ">=6.2.2" 944 | pyobjc-framework-SpriteKit = ">=6.2.2" 945 | 946 | [[package]] 947 | category = "main" 948 | description = "Wrappers for the framework ImageCaptureCore on macOS" 949 | marker = "platform_release >= \"10.0\"" 950 | name = "pyobjc-framework-imagecapturecore" 951 | optional = false 952 | python-versions = ">=3.6" 953 | version = "6.2.2" 954 | 955 | [package.dependencies] 956 | pyobjc-core = ">=6.2.2" 957 | pyobjc-framework-Cocoa = ">=6.2.2" 958 | 959 | [[package]] 960 | category = "main" 961 | description = "Wrappers for the framework IMServicePlugIn on macOS" 962 | marker = "platform_release >= \"11.0\"" 963 | name = "pyobjc-framework-imserviceplugin" 964 | optional = false 965 | python-versions = ">=3.6" 966 | version = "6.2.2" 967 | 968 | [package.dependencies] 969 | pyobjc-core = ">=6.2.2" 970 | pyobjc-framework-Cocoa = ">=6.2.2" 971 | 972 | [[package]] 973 | category = "main" 974 | description = "Wrappers for the framework InputMethodKit on macOS" 975 | marker = "platform_release >= \"9.0\"" 976 | name = "pyobjc-framework-inputmethodkit" 977 | optional = false 978 | python-versions = ">=3.6" 979 | version = "6.2.2" 980 | 981 | [package.dependencies] 982 | pyobjc-core = ">=6.2.2" 983 | pyobjc-framework-Cocoa = ">=6.2.2" 984 | 985 | [[package]] 986 | category = "main" 987 | description = "Wrappers for the framework InstallerPlugins on macOS" 988 | name = "pyobjc-framework-installerplugins" 989 | optional = false 990 | python-versions = ">=3.6" 991 | version = "6.2.2" 992 | 993 | [package.dependencies] 994 | pyobjc-core = ">=6.2.2" 995 | pyobjc-framework-Cocoa = ">=6.2.2" 996 | 997 | [[package]] 998 | category = "main" 999 | description = "Wrappers for the framework InstantMessage on macOS" 1000 | marker = "platform_release >= \"9.0\"" 1001 | name = "pyobjc-framework-instantmessage" 1002 | optional = false 1003 | python-versions = ">=3.6" 1004 | version = "6.2.2" 1005 | 1006 | [package.dependencies] 1007 | pyobjc-core = ">=6.2.2" 1008 | pyobjc-framework-Cocoa = ">=6.2.2" 1009 | pyobjc-framework-Quartz = ">=6.2.2" 1010 | 1011 | [[package]] 1012 | category = "main" 1013 | description = "Wrappers for the framework Intents on macOS" 1014 | marker = "platform_release >= \"16.0\"" 1015 | name = "pyobjc-framework-intents" 1016 | optional = false 1017 | python-versions = ">=3.6" 1018 | version = "6.2.2" 1019 | 1020 | [package.dependencies] 1021 | pyobjc-core = ">=6.2.2" 1022 | pyobjc-framework-Cocoa = ">=6.2.2" 1023 | 1024 | [[package]] 1025 | category = "main" 1026 | description = "Wrappers for the framework InterfaceBuilderKit on macOS" 1027 | marker = "platform_release >= \"9.0\" and platform_release < \"11.0\"" 1028 | name = "pyobjc-framework-interfacebuilderkit" 1029 | optional = false 1030 | python-versions = ">=3.6" 1031 | version = "6.2.2" 1032 | 1033 | [package.dependencies] 1034 | pyobjc-core = ">=6.2.2" 1035 | pyobjc-framework-Cocoa = ">=6.2.2" 1036 | 1037 | [[package]] 1038 | category = "main" 1039 | description = "Wrappers for the framework IOSurface on macOS" 1040 | marker = "platform_release >= \"10.0\"" 1041 | name = "pyobjc-framework-iosurface" 1042 | optional = false 1043 | python-versions = ">=3.6" 1044 | version = "6.2.2" 1045 | 1046 | [package.dependencies] 1047 | pyobjc-core = ">=6.2.2" 1048 | pyobjc-framework-Cocoa = ">=6.2.2" 1049 | 1050 | [[package]] 1051 | category = "main" 1052 | description = "Wrappers for the framework iTunesLibrary on macOS" 1053 | marker = "platform_release >= \"10.0\"" 1054 | name = "pyobjc-framework-ituneslibrary" 1055 | optional = false 1056 | python-versions = ">=3.6" 1057 | version = "6.2.2" 1058 | 1059 | [package.dependencies] 1060 | pyobjc-core = ">=6.2.2" 1061 | pyobjc-framework-Cocoa = ">=6.2.2" 1062 | 1063 | [[package]] 1064 | category = "main" 1065 | description = "Wrappers for the framework LatentSemanticMapping on macOS" 1066 | name = "pyobjc-framework-latentsemanticmapping" 1067 | optional = false 1068 | python-versions = ">=3.6" 1069 | version = "6.2.2" 1070 | 1071 | [package.dependencies] 1072 | pyobjc-core = ">=6.2.2" 1073 | pyobjc-framework-Cocoa = ">=6.2.2" 1074 | 1075 | [[package]] 1076 | category = "main" 1077 | description = "Wrappers for the framework LaunchServices on macOS" 1078 | name = "pyobjc-framework-launchservices" 1079 | optional = false 1080 | python-versions = ">=3.6" 1081 | version = "6.2.2" 1082 | 1083 | [package.dependencies] 1084 | pyobjc-core = ">=6.2.2" 1085 | pyobjc-framework-CoreServices = ">=6.2.2" 1086 | 1087 | [[package]] 1088 | category = "main" 1089 | description = "Wrappers for libdispatch on macOS" 1090 | marker = "platform_release >= \"12.0\"" 1091 | name = "pyobjc-framework-libdispatch" 1092 | optional = false 1093 | python-versions = ">=3.6" 1094 | version = "6.2.2" 1095 | 1096 | [package.dependencies] 1097 | pyobjc-core = ">=6.2.2" 1098 | 1099 | [[package]] 1100 | category = "main" 1101 | description = "Wrappers for the framework LinkPresentation on macOS" 1102 | marker = "platform_release >= \"19.0\"" 1103 | name = "pyobjc-framework-linkpresentation" 1104 | optional = false 1105 | python-versions = ">=3.6" 1106 | version = "6.2.2" 1107 | 1108 | [package.dependencies] 1109 | pyobjc-core = ">=6.2.2" 1110 | pyobjc-framework-Cocoa = ">=6.2.2" 1111 | pyobjc-framework-Quartz = ">=6.2.2" 1112 | 1113 | [[package]] 1114 | category = "main" 1115 | description = "Wrappers for the framework LocalAuthentication on macOS" 1116 | marker = "platform_release >= \"14.0\"" 1117 | name = "pyobjc-framework-localauthentication" 1118 | optional = false 1119 | python-versions = ">=3.6" 1120 | version = "6.2.2" 1121 | 1122 | [package.dependencies] 1123 | pyobjc-core = ">=6.2.2" 1124 | pyobjc-framework-Cocoa = ">=6.2.2" 1125 | 1126 | [[package]] 1127 | category = "main" 1128 | description = "Wrappers for the framework MapKit on macOS" 1129 | marker = "platform_release >= \"13.0\"" 1130 | name = "pyobjc-framework-mapkit" 1131 | optional = false 1132 | python-versions = ">=3.6" 1133 | version = "6.2.2" 1134 | 1135 | [package.dependencies] 1136 | pyobjc-core = ">=6.2.2" 1137 | pyobjc-framework-Cocoa = ">=6.2.2" 1138 | pyobjc-framework-CoreLocation = ">=6.2.2" 1139 | pyobjc-framework-Quartz = ">=6.2.2" 1140 | 1141 | [[package]] 1142 | category = "main" 1143 | description = "Wrappers for the framework MediaAccessibility on macOS" 1144 | marker = "platform_release >= \"13.0\"" 1145 | name = "pyobjc-framework-mediaaccessibility" 1146 | optional = false 1147 | python-versions = ">=3.6" 1148 | version = "6.2.2" 1149 | 1150 | [package.dependencies] 1151 | pyobjc-core = ">=6.2.2" 1152 | pyobjc-framework-Cocoa = ">=6.2.2" 1153 | 1154 | [[package]] 1155 | category = "main" 1156 | description = "Wrappers for the framework MediaLibrary on macOS" 1157 | marker = "platform_release >= \"13.0\"" 1158 | name = "pyobjc-framework-medialibrary" 1159 | optional = false 1160 | python-versions = ">=3.6" 1161 | version = "6.2.2" 1162 | 1163 | [package.dependencies] 1164 | pyobjc-core = ">=6.2.2" 1165 | pyobjc-framework-Cocoa = ">=6.2.2" 1166 | pyobjc-framework-Quartz = ">=6.2.2" 1167 | 1168 | [[package]] 1169 | category = "main" 1170 | description = "Wrappers for the framework MediaPlayer on macOS" 1171 | marker = "platform_release >= \"16.0\"" 1172 | name = "pyobjc-framework-mediaplayer" 1173 | optional = false 1174 | python-versions = ">=3.6" 1175 | version = "6.2.2" 1176 | 1177 | [package.dependencies] 1178 | pyobjc-core = ">=6.2.2" 1179 | pyobjc-framework-AVFoundation = ">=6.2.2" 1180 | 1181 | [[package]] 1182 | category = "main" 1183 | description = "Wrappers for the framework MediaToolbox on macOS" 1184 | marker = "platform_release >= \"13.0\"" 1185 | name = "pyobjc-framework-mediatoolbox" 1186 | optional = false 1187 | python-versions = ">=3.6" 1188 | version = "6.2.2" 1189 | 1190 | [package.dependencies] 1191 | pyobjc-core = ">=6.2.2" 1192 | pyobjc-framework-Cocoa = ">=6.2.2" 1193 | 1194 | [[package]] 1195 | category = "main" 1196 | description = "Wrappers for the framework Message on macOS" 1197 | marker = "platform_release < \"13.0\"" 1198 | name = "pyobjc-framework-message" 1199 | optional = false 1200 | python-versions = ">=3.6" 1201 | version = "6.2.2" 1202 | 1203 | [package.dependencies] 1204 | pyobjc-core = ">=6.2.2" 1205 | pyobjc-framework-Cocoa = ">=6.2.2" 1206 | 1207 | [[package]] 1208 | category = "main" 1209 | description = "Wrappers for the framework Metal on macOS" 1210 | marker = "platform_release >= \"15.0\"" 1211 | name = "pyobjc-framework-metal" 1212 | optional = false 1213 | python-versions = ">=3.6" 1214 | version = "6.2.2" 1215 | 1216 | [package.dependencies] 1217 | pyobjc-core = ">=6.2.2" 1218 | pyobjc-framework-Cocoa = ">=6.2.2" 1219 | 1220 | [[package]] 1221 | category = "main" 1222 | description = "Wrappers for the framework MetalKit on macOS" 1223 | marker = "platform_release >= \"15.0\"" 1224 | name = "pyobjc-framework-metalkit" 1225 | optional = false 1226 | python-versions = ">=3.6" 1227 | version = "6.2.2" 1228 | 1229 | [package.dependencies] 1230 | pyobjc-core = ">=6.2.2" 1231 | pyobjc-framework-Cocoa = ">=6.2.2" 1232 | pyobjc-framework-Metal = ">=6.2.2" 1233 | 1234 | [[package]] 1235 | category = "main" 1236 | description = "Wrappers for the framework ModelIO on macOS" 1237 | marker = "platform_release >= \"15.0\"" 1238 | name = "pyobjc-framework-modelio" 1239 | optional = false 1240 | python-versions = ">=3.6" 1241 | version = "6.2.2" 1242 | 1243 | [package.dependencies] 1244 | pyobjc-core = ">=6.2.2" 1245 | pyobjc-framework-Cocoa = ">=6.2.2" 1246 | pyobjc-framework-Quartz = ">=6.2.2" 1247 | 1248 | [[package]] 1249 | category = "main" 1250 | description = "Wrappers for the framework MultipeerConnectivity on macOS" 1251 | marker = "platform_release >= \"14.0\"" 1252 | name = "pyobjc-framework-multipeerconnectivity" 1253 | optional = false 1254 | python-versions = ">=3.6" 1255 | version = "6.2.2" 1256 | 1257 | [package.dependencies] 1258 | pyobjc-core = ">=6.2.2" 1259 | pyobjc-framework-Cocoa = ">=6.2.2" 1260 | 1261 | [[package]] 1262 | category = "main" 1263 | description = "Wrappers for the framework NaturalLanguage on macOS" 1264 | marker = "platform_release >= \"18.0\"" 1265 | name = "pyobjc-framework-naturallanguage" 1266 | optional = false 1267 | python-versions = ">=3.6" 1268 | version = "6.2.2" 1269 | 1270 | [package.dependencies] 1271 | pyobjc-core = ">=6.2.2" 1272 | pyobjc-framework-Cocoa = ">=6.2.2" 1273 | 1274 | [[package]] 1275 | category = "main" 1276 | description = "Wrappers for the framework NetFS on macOS" 1277 | marker = "platform_release >= \"10.0\"" 1278 | name = "pyobjc-framework-netfs" 1279 | optional = false 1280 | python-versions = ">=3.6" 1281 | version = "6.2.2" 1282 | 1283 | [package.dependencies] 1284 | pyobjc-core = ">=6.2.2" 1285 | pyobjc-framework-Cocoa = ">=6.2.2" 1286 | 1287 | [[package]] 1288 | category = "main" 1289 | description = "Wrappers for the framework Network on macOS" 1290 | marker = "platform_release >= \"18.0\"" 1291 | name = "pyobjc-framework-network" 1292 | optional = false 1293 | python-versions = ">=3.6" 1294 | version = "6.2.2" 1295 | 1296 | [package.dependencies] 1297 | pyobjc-core = ">=6.2.2" 1298 | pyobjc-framework-Cocoa = ">=6.2.2" 1299 | 1300 | [[package]] 1301 | category = "main" 1302 | description = "Wrappers for the framework NetworkExtension on macOS" 1303 | marker = "platform_release >= \"15.0\"" 1304 | name = "pyobjc-framework-networkextension" 1305 | optional = false 1306 | python-versions = ">=3.6" 1307 | version = "6.2.2" 1308 | 1309 | [package.dependencies] 1310 | pyobjc-core = ">=6.2.2" 1311 | pyobjc-framework-Cocoa = ">=6.2.2" 1312 | 1313 | [[package]] 1314 | category = "main" 1315 | description = "Wrappers for the framework NotificationCenter on macOS" 1316 | marker = "platform_release >= \"14.0\"" 1317 | name = "pyobjc-framework-notificationcenter" 1318 | optional = false 1319 | python-versions = ">=3.6" 1320 | version = "6.2.2" 1321 | 1322 | [package.dependencies] 1323 | pyobjc-core = ">=6.2.2" 1324 | pyobjc-framework-Cocoa = ">=6.2.2" 1325 | 1326 | [[package]] 1327 | category = "main" 1328 | description = "Wrappers for the framework OpenDirectory on macOS" 1329 | marker = "platform_release >= \"10.0\"" 1330 | name = "pyobjc-framework-opendirectory" 1331 | optional = false 1332 | python-versions = ">=3.6" 1333 | version = "6.2.2" 1334 | 1335 | [package.dependencies] 1336 | pyobjc-core = ">=6.2.2" 1337 | pyobjc-framework-Cocoa = ">=6.2.2" 1338 | 1339 | [[package]] 1340 | category = "main" 1341 | description = "Wrappers for the framework OSAKit on macOS" 1342 | name = "pyobjc-framework-osakit" 1343 | optional = false 1344 | python-versions = ">=3.6" 1345 | version = "6.2.2" 1346 | 1347 | [package.dependencies] 1348 | pyobjc-core = ">=6.2.2" 1349 | pyobjc-framework-Cocoa = ">=6.2.2" 1350 | 1351 | [[package]] 1352 | category = "main" 1353 | description = "Wrappers for the framework OSLog on macOS" 1354 | marker = "platform_release >= \"19.0\"" 1355 | name = "pyobjc-framework-oslog" 1356 | optional = false 1357 | python-versions = ">=3.6" 1358 | version = "6.2.2" 1359 | 1360 | [package.dependencies] 1361 | pyobjc-core = ">=6.2.2" 1362 | pyobjc-framework-Cocoa = ">=6.2.2" 1363 | pyobjc-framework-CoreMedia = ">=6.2.2" 1364 | pyobjc-framework-Quartz = ">=6.2.2" 1365 | 1366 | [[package]] 1367 | category = "main" 1368 | description = "Wrappers for the framework PencilKit on macOS" 1369 | marker = "platform_release >= \"19.0\"" 1370 | name = "pyobjc-framework-pencilkit" 1371 | optional = false 1372 | python-versions = ">=3.6" 1373 | version = "6.2.2" 1374 | 1375 | [package.dependencies] 1376 | pyobjc-core = ">=6.2.2" 1377 | pyobjc-framework-Cocoa = ">=6.2.2" 1378 | 1379 | [[package]] 1380 | category = "main" 1381 | description = "Wrappers for the framework Photos on macOS" 1382 | marker = "platform_release >= \"15.0\"" 1383 | name = "pyobjc-framework-photos" 1384 | optional = false 1385 | python-versions = ">=3.6" 1386 | version = "6.2.2" 1387 | 1388 | [package.dependencies] 1389 | pyobjc-core = ">=6.2.2" 1390 | pyobjc-framework-Cocoa = ">=6.2.2" 1391 | 1392 | [[package]] 1393 | category = "main" 1394 | description = "Wrappers for the framework PhotosUI on macOS" 1395 | marker = "platform_release >= \"15.0\"" 1396 | name = "pyobjc-framework-photosui" 1397 | optional = false 1398 | python-versions = ">=3.6" 1399 | version = "6.2.2" 1400 | 1401 | [package.dependencies] 1402 | pyobjc-core = ">=6.2.2" 1403 | pyobjc-framework-Cocoa = ">=6.2.2" 1404 | 1405 | [[package]] 1406 | category = "main" 1407 | description = "Wrappers for the framework PreferencePanes on macOS" 1408 | name = "pyobjc-framework-preferencepanes" 1409 | optional = false 1410 | python-versions = ">=3.6" 1411 | version = "6.2.2" 1412 | 1413 | [package.dependencies] 1414 | pyobjc-core = ">=6.2.2" 1415 | pyobjc-framework-Cocoa = ">=6.2.2" 1416 | 1417 | [[package]] 1418 | category = "main" 1419 | description = "Wrappers for the framework PubSub on macOS" 1420 | marker = "platform_release >= \"9.0\" and platform_release < \"18.0\"" 1421 | name = "pyobjc-framework-pubsub" 1422 | optional = false 1423 | python-versions = ">=3.6" 1424 | version = "6.2.2" 1425 | 1426 | [package.dependencies] 1427 | pyobjc-core = ">=6.2.2" 1428 | pyobjc-framework-Cocoa = ">=6.2.2" 1429 | 1430 | [[package]] 1431 | category = "main" 1432 | description = "Wrappers for the framework PushKit on macOS" 1433 | marker = "platform_release >= \"19.0\"" 1434 | name = "pyobjc-framework-pushkit" 1435 | optional = false 1436 | python-versions = ">=3.6" 1437 | version = "6.2.2" 1438 | 1439 | [package.dependencies] 1440 | pyobjc-core = ">=6.2.2" 1441 | pyobjc-framework-Cocoa = ">=6.2.2" 1442 | 1443 | [[package]] 1444 | category = "main" 1445 | description = "Wrappers for the framework QTKit on macOS" 1446 | marker = "platform_release >= \"9.0\" and platform_release < \"19.0\"" 1447 | name = "pyobjc-framework-qtkit" 1448 | optional = false 1449 | python-versions = ">=3.6" 1450 | version = "6.2.2" 1451 | 1452 | [package.dependencies] 1453 | pyobjc-core = ">=6.2.2" 1454 | pyobjc-framework-Cocoa = ">=6.2.2" 1455 | pyobjc-framework-Quartz = ">=6.2.2" 1456 | 1457 | [[package]] 1458 | category = "main" 1459 | description = "Wrappers for the Quartz frameworks on macOS" 1460 | name = "pyobjc-framework-quartz" 1461 | optional = false 1462 | python-versions = ">=3.6" 1463 | version = "6.2.2" 1464 | 1465 | [package.dependencies] 1466 | pyobjc-core = ">=6.2.2" 1467 | pyobjc-framework-Cocoa = ">=6.2.2" 1468 | 1469 | [[package]] 1470 | category = "main" 1471 | description = "Wrappers for the framework QuickLookThumbnailing on macOS" 1472 | marker = "platform_release >= \"19.0\"" 1473 | name = "pyobjc-framework-quicklookthumbnailing" 1474 | optional = false 1475 | python-versions = ">=3.6" 1476 | version = "6.2.2" 1477 | 1478 | [package.dependencies] 1479 | pyobjc-core = ">=6.2.2" 1480 | pyobjc-framework-Cocoa = ">=6.2.2" 1481 | pyobjc-framework-Quartz = ">=6.2.2" 1482 | 1483 | [[package]] 1484 | category = "main" 1485 | description = "Wrappers for the framework SafariServices on macOS" 1486 | marker = "platform_release >= \"15.0\"" 1487 | name = "pyobjc-framework-safariservices" 1488 | optional = false 1489 | python-versions = ">=3.6" 1490 | version = "6.2.2" 1491 | 1492 | [package.dependencies] 1493 | pyobjc-core = ">=6.2.2" 1494 | pyobjc-framework-Cocoa = ">=6.2.2" 1495 | 1496 | [[package]] 1497 | category = "main" 1498 | description = "Wrappers for the framework SceneKit on macOS" 1499 | marker = "platform_release >= \"11.0\"" 1500 | name = "pyobjc-framework-scenekit" 1501 | optional = false 1502 | python-versions = ">=3.6" 1503 | version = "6.2.2" 1504 | 1505 | [package.dependencies] 1506 | pyobjc-core = ">=6.2.2" 1507 | pyobjc-framework-Cocoa = ">=6.2.2" 1508 | pyobjc-framework-Quartz = ">=6.2.2" 1509 | 1510 | [[package]] 1511 | category = "main" 1512 | description = "Wrappers for the framework ScreenSaver on macOS" 1513 | name = "pyobjc-framework-screensaver" 1514 | optional = false 1515 | python-versions = ">=3.6" 1516 | version = "6.2.2" 1517 | 1518 | [package.dependencies] 1519 | pyobjc-core = ">=6.2.2" 1520 | pyobjc-framework-Cocoa = ">=6.2.2" 1521 | 1522 | [[package]] 1523 | category = "main" 1524 | description = "Wrappers for the framework ScriptingBridge on macOS" 1525 | marker = "platform_release >= \"9.0\"" 1526 | name = "pyobjc-framework-scriptingbridge" 1527 | optional = false 1528 | python-versions = ">=3.6" 1529 | version = "6.2.2" 1530 | 1531 | [package.dependencies] 1532 | pyobjc-core = ">=6.2.2" 1533 | pyobjc-framework-Cocoa = ">=6.2.2" 1534 | 1535 | [[package]] 1536 | category = "main" 1537 | description = "Wrappers for the framework SearchKit on macOS" 1538 | name = "pyobjc-framework-searchkit" 1539 | optional = false 1540 | python-versions = ">=3.6" 1541 | version = "6.2.2" 1542 | 1543 | [package.dependencies] 1544 | pyobjc-core = ">=6.2.2" 1545 | pyobjc-framework-CoreServices = ">=6.2.2" 1546 | 1547 | [[package]] 1548 | category = "main" 1549 | description = "Wrappers for the framework Security on macOS" 1550 | name = "pyobjc-framework-security" 1551 | optional = false 1552 | python-versions = ">=3.6" 1553 | version = "6.2.2" 1554 | 1555 | [package.dependencies] 1556 | pyobjc-core = ">=6.2.2" 1557 | pyobjc-framework-Cocoa = ">=6.2.2" 1558 | 1559 | [[package]] 1560 | category = "main" 1561 | description = "Wrappers for the framework SecurityFoundation on macOS" 1562 | name = "pyobjc-framework-securityfoundation" 1563 | optional = false 1564 | python-versions = ">=3.6" 1565 | version = "6.2.2" 1566 | 1567 | [package.dependencies] 1568 | pyobjc-core = ">=6.2.2" 1569 | pyobjc-framework-Cocoa = ">=6.2.2" 1570 | pyobjc-framework-Security = ">=6.2.2" 1571 | 1572 | [[package]] 1573 | category = "main" 1574 | description = "Wrappers for the framework SecurityInterface on macOS" 1575 | name = "pyobjc-framework-securityinterface" 1576 | optional = false 1577 | python-versions = ">=3.6" 1578 | version = "6.2.2" 1579 | 1580 | [package.dependencies] 1581 | pyobjc-core = ">=6.2.2" 1582 | pyobjc-framework-Cocoa = ">=6.2.2" 1583 | pyobjc-framework-Security = ">=6.2.2" 1584 | 1585 | [[package]] 1586 | category = "main" 1587 | description = "Wrappers for the framework ServerNotification on macOS" 1588 | marker = "platform_release >= \"10.0\" and platform_release < \"13.0\"" 1589 | name = "pyobjc-framework-servernotification" 1590 | optional = false 1591 | python-versions = ">=3.6" 1592 | version = "6.2.2" 1593 | 1594 | [package.dependencies] 1595 | pyobjc-core = ">=6.2.2" 1596 | pyobjc-framework-Cocoa = ">=6.2.2" 1597 | 1598 | [[package]] 1599 | category = "main" 1600 | description = "Wrappers for the framework ServiceManagement on macOS" 1601 | marker = "platform_release >= \"10.0\"" 1602 | name = "pyobjc-framework-servicemanagement" 1603 | optional = false 1604 | python-versions = ">=3.6" 1605 | version = "6.2.2" 1606 | 1607 | [package.dependencies] 1608 | pyobjc-core = ">=6.2.2" 1609 | pyobjc-framework-Cocoa = ">=6.2.2" 1610 | 1611 | [[package]] 1612 | category = "main" 1613 | description = "Wrappers for the framework Social on macOS" 1614 | marker = "platform_release >= \"12.0\"" 1615 | name = "pyobjc-framework-social" 1616 | optional = false 1617 | python-versions = ">=3.6" 1618 | version = "6.2.2" 1619 | 1620 | [package.dependencies] 1621 | pyobjc-core = ">=6.2.2" 1622 | pyobjc-framework-Cocoa = ">=6.2.2" 1623 | 1624 | [[package]] 1625 | category = "main" 1626 | description = "Wrappers for the framework SoundAnalysis on macOS" 1627 | marker = "platform_release >= \"19.0\"" 1628 | name = "pyobjc-framework-soundanalysis" 1629 | optional = false 1630 | python-versions = ">=3.6" 1631 | version = "6.2.2" 1632 | 1633 | [package.dependencies] 1634 | pyobjc-core = ">=6.2.2" 1635 | pyobjc-framework-Cocoa = ">=6.2.2" 1636 | 1637 | [[package]] 1638 | category = "main" 1639 | description = "Wrappers for the framework Speech on macOS" 1640 | marker = "platform_release >= \"19.0\"" 1641 | name = "pyobjc-framework-speech" 1642 | optional = false 1643 | python-versions = ">=3.6" 1644 | version = "6.2.2" 1645 | 1646 | [package.dependencies] 1647 | pyobjc-core = ">=6.2.2" 1648 | pyobjc-framework-Cocoa = ">=6.2.2" 1649 | 1650 | [[package]] 1651 | category = "main" 1652 | description = "Wrappers for the framework SpriteKit on macOS" 1653 | marker = "platform_release >= \"13.0\" or platform_release >= \"15.0\"" 1654 | name = "pyobjc-framework-spritekit" 1655 | optional = false 1656 | python-versions = ">=3.6" 1657 | version = "6.2.2" 1658 | 1659 | [package.dependencies] 1660 | pyobjc-core = ">=6.2.2" 1661 | pyobjc-framework-Cocoa = ">=6.2.2" 1662 | pyobjc-framework-Quartz = ">=6.2.2" 1663 | 1664 | [[package]] 1665 | category = "main" 1666 | description = "Wrappers for the framework StoreKit on macOS" 1667 | marker = "platform_release >= \"11.0\"" 1668 | name = "pyobjc-framework-storekit" 1669 | optional = false 1670 | python-versions = ">=3.6" 1671 | version = "6.2.2" 1672 | 1673 | [package.dependencies] 1674 | pyobjc-core = ">=6.2.2" 1675 | pyobjc-framework-Cocoa = ">=6.2.2" 1676 | 1677 | [[package]] 1678 | category = "main" 1679 | description = "Wrappers for the framework SyncServices on macOS" 1680 | name = "pyobjc-framework-syncservices" 1681 | optional = false 1682 | python-versions = ">=3.6" 1683 | version = "6.2.2" 1684 | 1685 | [package.dependencies] 1686 | pyobjc-core = ">=6.2.2" 1687 | pyobjc-framework-Cocoa = ">=6.2.2" 1688 | pyobjc-framework-CoreData = ">=6.2.2" 1689 | 1690 | [[package]] 1691 | category = "main" 1692 | description = "Wrappers for the framework SystemConfiguration on macOS" 1693 | name = "pyobjc-framework-systemconfiguration" 1694 | optional = false 1695 | python-versions = ">=3.6" 1696 | version = "6.2.2" 1697 | 1698 | [package.dependencies] 1699 | pyobjc-core = ">=6.2.2" 1700 | pyobjc-framework-Cocoa = ">=6.2.2" 1701 | 1702 | [[package]] 1703 | category = "main" 1704 | description = "Wrappers for the framework SystemExtensions on macOS" 1705 | marker = "platform_release >= \"19.0\"" 1706 | name = "pyobjc-framework-systemextensions" 1707 | optional = false 1708 | python-versions = ">=3.6" 1709 | version = "6.2.2" 1710 | 1711 | [package.dependencies] 1712 | pyobjc-core = ">=6.2.2" 1713 | pyobjc-framework-Cocoa = ">=6.2.2" 1714 | 1715 | [[package]] 1716 | category = "main" 1717 | description = "Wrappers for the framework UserNotifications on macOS" 1718 | marker = "platform_release >= \"18.0\"" 1719 | name = "pyobjc-framework-usernotifications" 1720 | optional = false 1721 | python-versions = ">=3.6" 1722 | version = "6.2.2" 1723 | 1724 | [package.dependencies] 1725 | pyobjc-core = ">=6.2.2" 1726 | pyobjc-framework-Cocoa = ">=6.2.2" 1727 | 1728 | [[package]] 1729 | category = "main" 1730 | description = "Wrappers for the framework VideoSubscriberAccount on macOS" 1731 | marker = "platform_release >= \"18.0\"" 1732 | name = "pyobjc-framework-videosubscriberaccount" 1733 | optional = false 1734 | python-versions = ">=3.6" 1735 | version = "6.2.2" 1736 | 1737 | [package.dependencies] 1738 | pyobjc-core = ">=6.2.2" 1739 | pyobjc-framework-Cocoa = ">=6.2.2" 1740 | 1741 | [[package]] 1742 | category = "main" 1743 | description = "Wrappers for the framework VideoToolbox on macOS" 1744 | marker = "platform_release >= \"12.0\"" 1745 | name = "pyobjc-framework-videotoolbox" 1746 | optional = false 1747 | python-versions = ">=3.6" 1748 | version = "6.2.2" 1749 | 1750 | [package.dependencies] 1751 | pyobjc-core = ">=6.2.2" 1752 | pyobjc-framework-Cocoa = ">=6.2.2" 1753 | pyobjc-framework-CoreMedia = ">=6.2.2" 1754 | pyobjc-framework-Quartz = ">=6.2.2" 1755 | 1756 | [[package]] 1757 | category = "main" 1758 | description = "Wrappers for the framework Vision on macOS" 1759 | marker = "platform_release >= \"17.0\"" 1760 | name = "pyobjc-framework-vision" 1761 | optional = false 1762 | python-versions = ">=3.6" 1763 | version = "6.2.2" 1764 | 1765 | [package.dependencies] 1766 | pyobjc-core = ">=6.2.2" 1767 | pyobjc-framework-Cocoa = ">=6.2.2" 1768 | pyobjc-framework-CoreML = ">=6.2.2" 1769 | pyobjc-framework-Quartz = ">=6.2.2" 1770 | 1771 | [[package]] 1772 | category = "main" 1773 | description = "Wrappers for the framework WebKit on macOS" 1774 | name = "pyobjc-framework-webkit" 1775 | optional = false 1776 | python-versions = ">=3.6" 1777 | version = "6.2.2" 1778 | 1779 | [package.dependencies] 1780 | pyobjc-core = ">=6.2.2" 1781 | pyobjc-framework-Cocoa = ">=6.2.2" 1782 | 1783 | [[package]] 1784 | category = "main" 1785 | description = "Wrappers for the framework XgridFoundation on macOS" 1786 | marker = "platform_release < \"12.0\"" 1787 | name = "pyobjc-framework-xgridfoundation" 1788 | optional = false 1789 | python-versions = ">=3.6" 1790 | version = "6.2.2" 1791 | 1792 | [package.dependencies] 1793 | pyobjc-core = ">=6.2.2" 1794 | pyobjc-framework-Cocoa = ">=6.2.2" 1795 | 1796 | [[package]] 1797 | category = "dev" 1798 | description = "YAML parser and emitter for Python" 1799 | name = "pyyaml" 1800 | optional = false 1801 | python-versions = "*" 1802 | version = "5.3.1" 1803 | 1804 | [[package]] 1805 | category = "dev" 1806 | description = "Python 2 and 3 compatibility utilities" 1807 | name = "six" 1808 | optional = false 1809 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 1810 | version = "1.15.0" 1811 | 1812 | [[package]] 1813 | category = "dev" 1814 | description = "Python Library for Tom's Obvious, Minimal Language" 1815 | name = "toml" 1816 | optional = false 1817 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 1818 | version = "0.10.2" 1819 | 1820 | [[package]] 1821 | category = "dev" 1822 | description = "Virtual Python Environment builder" 1823 | name = "virtualenv" 1824 | optional = false 1825 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 1826 | version = "20.1.0" 1827 | 1828 | [package.dependencies] 1829 | appdirs = ">=1.4.3,<2" 1830 | distlib = ">=0.3.1,<1" 1831 | filelock = ">=3.0.0,<4" 1832 | six = ">=1.9.0,<2" 1833 | 1834 | [package.dependencies.importlib-metadata] 1835 | python = "<3.8" 1836 | version = ">=0.12,<3" 1837 | 1838 | [package.extras] 1839 | docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] 1840 | testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] 1841 | 1842 | [[package]] 1843 | category = "dev" 1844 | description = "Backport of pathlib-compatible object wrapper for zip files" 1845 | marker = "python_version < \"3.8\"" 1846 | name = "zipp" 1847 | optional = false 1848 | python-versions = ">=3.6" 1849 | version = "3.4.0" 1850 | 1851 | [package.extras] 1852 | docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] 1853 | testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] 1854 | 1855 | [metadata] 1856 | content-hash = "52a303f8a3758c1a102f432f4f212b645646a0a5970689df387c8d4c3533d5b4" 1857 | python-versions = "^3.7" 1858 | 1859 | [metadata.files] 1860 | appdirs = [ 1861 | {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, 1862 | {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, 1863 | ] 1864 | "aspy.yaml" = [ 1865 | {file = "aspy.yaml-1.3.0-py2.py3-none-any.whl", hash = "sha256:463372c043f70160a9ec950c3f1e4c3a82db5fca01d334b6bc89c7164d744bdc"}, 1866 | {file = "aspy.yaml-1.3.0.tar.gz", hash = "sha256:e7c742382eff2caed61f87a39d13f99109088e5e93f04d76eb8d4b28aa143f45"}, 1867 | ] 1868 | cfgv = [ 1869 | {file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"}, 1870 | {file = "cfgv-3.2.0.tar.gz", hash = "sha256:cf22deb93d4bcf92f345a5c3cd39d3d41d6340adc60c78bbbd6588c384fda6a1"}, 1871 | ] 1872 | click = [ 1873 | {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, 1874 | {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, 1875 | ] 1876 | distlib = [ 1877 | {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, 1878 | {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, 1879 | ] 1880 | filelock = [ 1881 | {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, 1882 | {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, 1883 | ] 1884 | identify = [ 1885 | {file = "identify-1.5.9-py2.py3-none-any.whl", hash = "sha256:5dd84ac64a9a115b8e0b27d1756b244b882ad264c3c423f42af8235a6e71ca12"}, 1886 | {file = "identify-1.5.9.tar.gz", hash = "sha256:c9504ba6a043ee2db0a9d69e43246bc138034895f6338d5aed1b41e4a73b1513"}, 1887 | ] 1888 | importlib-metadata = [ 1889 | {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"}, 1890 | {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"}, 1891 | ] 1892 | mutagen = [ 1893 | {file = "mutagen-1.45.1-py3-none-any.whl", hash = "sha256:9c9f243fcec7f410f138cb12c21c84c64fde4195481a30c9bfb05b5f003adfed"}, 1894 | {file = "mutagen-1.45.1.tar.gz", hash = "sha256:6397602efb3c2d7baebd2166ed85731ae1c1d475abca22090b7141ff5034b3e1"}, 1895 | ] 1896 | nodeenv = [ 1897 | {file = "nodeenv-1.5.0-py2.py3-none-any.whl", hash = "sha256:5304d424c529c997bc888453aeaa6362d242b6b4631e90f3d4bf1b290f1c84a9"}, 1898 | {file = "nodeenv-1.5.0.tar.gz", hash = "sha256:ab45090ae383b716c4ef89e690c41ff8c2b257b85b309f01f3654df3d084bd7c"}, 1899 | ] 1900 | pillow = [ 1901 | {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"}, 1902 | {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"}, 1903 | {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"}, 1904 | {file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"}, 1905 | {file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"}, 1906 | {file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"}, 1907 | {file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"}, 1908 | {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"}, 1909 | {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"}, 1910 | {file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"}, 1911 | {file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"}, 1912 | {file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"}, 1913 | {file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"}, 1914 | {file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"}, 1915 | {file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"}, 1916 | {file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"}, 1917 | {file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"}, 1918 | {file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"}, 1919 | {file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"}, 1920 | {file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"}, 1921 | {file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"}, 1922 | {file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"}, 1923 | {file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"}, 1924 | {file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"}, 1925 | {file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"}, 1926 | {file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"}, 1927 | {file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"}, 1928 | {file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"}, 1929 | ] 1930 | pre-commit = [ 1931 | {file = "pre_commit-1.21.0-py2.py3-none-any.whl", hash = "sha256:f92a359477f3252452ae2e8d3029de77aec59415c16ae4189bcfba40b757e029"}, 1932 | {file = "pre_commit-1.21.0.tar.gz", hash = "sha256:8f48d8637bdae6fa70cc97db9c1dd5aa7c5c8bf71968932a380628c25978b850"}, 1933 | ] 1934 | pyobjc = [ 1935 | {file = "pyobjc-6.2.2-py3-none-any.whl", hash = "sha256:dc2e4fb96bc48770c1b5810eb65bf446c50fbf2faf6a6a398c31556b404e015c"}, 1936 | {file = "pyobjc-6.2.2.tar.gz", hash = "sha256:d5b87e9fa4cc9b51bf37f9a461887e2d8b9ae7e6bb45675f8edbe35ea6770455"}, 1937 | ] 1938 | pyobjc-core = [ 1939 | {file = "pyobjc-core-6.2.2.tar.gz", hash = "sha256:38e7b15a042439dadd18b28b78229e52fb882460fc16ddbae342b9972d5a827c"}, 1940 | {file = "pyobjc_core-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:73938398559b718595076fce4921022f21983dd85ebace3ecbe6182697abe164"}, 1941 | {file = "pyobjc_core-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:60d0c57de915b6ed91a9a26e3bdefdcaeb1288623c69f291338208c5a227d190"}, 1942 | {file = "pyobjc_core-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be312b7a0edb45dd8ea68e70f2b411b59677d4ceb513c48eace73cb78dbfd85f"}, 1943 | {file = "pyobjc_core-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47a89171d218905dbf13011b1a7d698c246cb66fb5f14119bc0d9e039d0486fa"}, 1944 | ] 1945 | pyobjc-framework-accounts = [ 1946 | {file = "pyobjc-framework-Accounts-6.2.2.tar.gz", hash = "sha256:9ecf1d03f856617b3ace091bd844ab8ae3f6122ed83cffd4a2c067da19ea2386"}, 1947 | {file = "pyobjc_framework_Accounts-6.2.2-py2.py3-none-any.whl", hash = "sha256:2dfe6c2d02f0f4d8912cf5dffd66812789daff5e46ac08675505ac1a9979c442"}, 1948 | ] 1949 | pyobjc-framework-addressbook = [ 1950 | {file = "pyobjc-framework-AddressBook-6.2.2.tar.gz", hash = "sha256:d6f410dc4ac0465b678b2c3d04c870fad387019a5aa2cb27101f43e488e935f0"}, 1951 | {file = "pyobjc_framework_AddressBook-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6b17571fe93b20a1649928a644013ef6daf3d4835d7ff4f1cc1fca8070f29513"}, 1952 | ] 1953 | pyobjc-framework-adsupport = [ 1954 | {file = "pyobjc-framework-AdSupport-6.2.2.tar.gz", hash = "sha256:91851a170b1b2bd9392bdb6cf4cbb9e449950596b5244d4d8098933ab68c5b87"}, 1955 | {file = "pyobjc_framework_AdSupport-6.2.2-py2.py3-none-any.whl", hash = "sha256:92fc08e7089568f67b8bab11aabc60c9287f1aefefee0736ea580d8ff37bccfd"}, 1956 | ] 1957 | pyobjc-framework-applescriptkit = [ 1958 | {file = "pyobjc-framework-AppleScriptKit-6.2.2.tar.gz", hash = "sha256:fa7821d67503997db4e6b77f0d3e855a6564a627e2e2f3e99a83110365971492"}, 1959 | {file = "pyobjc_framework_AppleScriptKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:4d81cc4d0703cc4ad8a4e4e38958e1ccb1fad951efc801b6753883d4f76c984b"}, 1960 | ] 1961 | pyobjc-framework-applescriptobjc = [ 1962 | {file = "pyobjc-framework-AppleScriptObjC-6.2.2.tar.gz", hash = "sha256:581c51e102a266c57bccd3c56625e5fe9f9069c88f9b6510e3f6bf47cc92ddb2"}, 1963 | {file = "pyobjc_framework_AppleScriptObjC-6.2.2-py2.py3-none-any.whl", hash = "sha256:7466ef8b6726f66eae102c77d59fdce3961b4b74a87f331f14683092203d2609"}, 1964 | ] 1965 | pyobjc-framework-applicationservices = [ 1966 | {file = "pyobjc-framework-ApplicationServices-6.2.2.tar.gz", hash = "sha256:f9d74f1d72713180638fc441c072eaaa8e59ccabb04bac18b21d137e9c0cb5e6"}, 1967 | {file = "pyobjc_framework_ApplicationServices-6.2.2-py2.py3-none-any.whl", hash = "sha256:9018463ad698e6bb4f4dfb01cd3157b521b68ace447df8cceff17c2b99d0ebc9"}, 1968 | ] 1969 | pyobjc-framework-authenticationservices = [ 1970 | {file = "pyobjc-framework-AuthenticationServices-6.2.2.tar.gz", hash = "sha256:a5229d9a7d878e8287a518a1ad9f7e4a2efccd19d952561498292f3e0037a08d"}, 1971 | {file = "pyobjc_framework_AuthenticationServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:45ae3dc42f233bb810d94da2438821ac2849ad0fa7eb0f4cf25f4d4c77326381"}, 1972 | ] 1973 | pyobjc-framework-automaticassessmentconfiguration = [ 1974 | {file = "pyobjc-framework-AutomaticAssessmentConfiguration-6.2.2.tar.gz", hash = "sha256:9b9488f23e31ec4b217777eae4f46e64d85479c0b0250c59aaa7b47342462a83"}, 1975 | {file = "pyobjc_framework_AutomaticAssessmentConfiguration-6.2.2-py2.py3-none-any.whl", hash = "sha256:07650b5975ade6cf21e65eba74029fecceb36982fd2b9896b2bc282a2964988e"}, 1976 | ] 1977 | pyobjc-framework-automator = [ 1978 | {file = "pyobjc-framework-Automator-6.2.2.tar.gz", hash = "sha256:bd071eb8d9a3286b92713afb24792e5b777c6deb57c1deaca4236503256b5971"}, 1979 | {file = "pyobjc_framework_Automator-6.2.2-py2.py3-none-any.whl", hash = "sha256:53d257d6a0ae7fa78d9c2d7cfbdb27b5bcf87576c3be0f2d61d560f34e00ab5b"}, 1980 | ] 1981 | pyobjc-framework-avfoundation = [ 1982 | {file = "pyobjc-framework-AVFoundation-6.2.2.tar.gz", hash = "sha256:9d347c71b99f900770b7fb93881fa30a43d61bd8b9390b432878acff0edfe2fb"}, 1983 | {file = "pyobjc_framework_AVFoundation-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f7ab7f751127af71b99e043c4bfb028e7f5cd62675c211d878ef1d6a6096ff01"}, 1984 | ] 1985 | pyobjc-framework-avkit = [ 1986 | {file = "pyobjc-framework-AVKit-6.2.2.tar.gz", hash = "sha256:3095b626fd9a50efe22af67597f0af8e4409f47edf4527b355822c074c28a122"}, 1987 | {file = "pyobjc_framework_AVKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2b3dfe6c2aa4bb084e4d82c8633bf3c40be18f32c698caae4e806124d9eb5739"}, 1988 | ] 1989 | pyobjc-framework-businesschat = [ 1990 | {file = "pyobjc-framework-BusinessChat-6.2.2.tar.gz", hash = "sha256:7772ca33d394adfd85685a80371d367d09098ebb3fb0712d1649f504e05975a6"}, 1991 | {file = "pyobjc_framework_BusinessChat-6.2.2-py2.py3-none-any.whl", hash = "sha256:ad520cc0790acb3adfaf606ac930e9b822faf1066afb3b4b2df18fd66666e32c"}, 1992 | ] 1993 | pyobjc-framework-calendarstore = [ 1994 | {file = "pyobjc-framework-CalendarStore-6.2.2.tar.gz", hash = "sha256:1ec03bc5bbef9cdbf4e8520774da28d1f6d0e1581905f15d639211926ec5f884"}, 1995 | {file = "pyobjc_framework_CalendarStore-6.2.2-py2.py3-none-any.whl", hash = "sha256:c5c215cc2ed762d94e8f40b18ff907561e2dc604acd2d40d370fb5edd2ccb7d7"}, 1996 | ] 1997 | pyobjc-framework-cfnetwork = [ 1998 | {file = "pyobjc-framework-CFNetwork-6.2.2.tar.gz", hash = "sha256:fbf1064e642a593f1001c86f9497a1b0627d8583354576e95f8e1e240a3cd553"}, 1999 | {file = "pyobjc_framework_CFNetwork-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2dab65518831570efb830b9005c6775ae040de7c70a0c5b2110c86f5cd45b905"}, 2000 | ] 2001 | pyobjc-framework-cloudkit = [ 2002 | {file = "pyobjc-framework-CloudKit-6.2.2.tar.gz", hash = "sha256:351335710aed1f04cb73b3d4a983835a8b40f04b625937c81a13a52a5dfe9313"}, 2003 | {file = "pyobjc_framework_CloudKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:1a730fcf1f09bf914011e4534cbfa8f25c7a4f598754a0076140537434f8e66d"}, 2004 | ] 2005 | pyobjc-framework-cocoa = [ 2006 | {file = "pyobjc-framework-Cocoa-6.2.2.tar.gz", hash = "sha256:75821b98fb789d240bea7034c4f96396b2eac3e7b02428b4be9101fc899b7fc3"}, 2007 | {file = "pyobjc_framework_Cocoa-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:779299f73b8b5a1dd0973b3b16bd706e1f67df44edfb3f3ca6e5e873591c0efc"}, 2008 | {file = "pyobjc_framework_Cocoa-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:45e3011efbd8ab4eb4c7ee1f55a8b5ecb41cf66fa797aff0e9454060781645a0"}, 2009 | {file = "pyobjc_framework_Cocoa-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2a5ab2e33cafe577592c31b2663f3b23f6e142fd717c8cf3826394a380cc4353"}, 2010 | {file = "pyobjc_framework_Cocoa-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f5e1d59f6e1f4be40dedf051925b8d90c561657c9ec2453652af033fe5c2bf0"}, 2011 | ] 2012 | pyobjc-framework-collaboration = [ 2013 | {file = "pyobjc-framework-Collaboration-6.2.2.tar.gz", hash = "sha256:3751f1895b2e1cc92674fbdad2b64f6cce1cb5aab50730b7bb8c6c282c76b7ec"}, 2014 | {file = "pyobjc_framework_Collaboration-6.2.2-py2.py3-none-any.whl", hash = "sha256:f703b36dba48b73f81695fd8908a82e5d7c292e7a2cab2142dbb979bff0b8ef3"}, 2015 | ] 2016 | pyobjc-framework-colorsync = [ 2017 | {file = "pyobjc-framework-ColorSync-6.2.2.tar.gz", hash = "sha256:c87f186ad71af827fa11799318680167de292de580f2da0c9bfb3097ab61523f"}, 2018 | {file = "pyobjc_framework_ColorSync-6.2.2-py2.py3-none-any.whl", hash = "sha256:a2010756da26940001f4162588927d5cab3da559f0d06f0b7f1d3ffea91deed0"}, 2019 | ] 2020 | pyobjc-framework-contacts = [ 2021 | {file = "pyobjc-framework-Contacts-6.2.2.tar.gz", hash = "sha256:92dcd6bd63e07214fcb20b37906b0bd468cb94dc317d3ae8f140a712eea83c2d"}, 2022 | {file = "pyobjc_framework_Contacts-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:78dd356c81edf32b341595121a6192a0a5c66de97068a0c825200c50f1319cf4"}, 2023 | ] 2024 | pyobjc-framework-contactsui = [ 2025 | {file = "pyobjc-framework-ContactsUI-6.2.2.tar.gz", hash = "sha256:b6a649ebae15d7cb36a06003fbd0cb5fa948f5ce92652a753b1cb1beda47e409"}, 2026 | {file = "pyobjc_framework_ContactsUI-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a66628723ea5cee14e0fe983db2f550e96c1be5d4a8809a6f0596629ba40fe4e"}, 2027 | ] 2028 | pyobjc-framework-coreaudio = [ 2029 | {file = "pyobjc-framework-CoreAudio-6.2.2.tar.gz", hash = "sha256:a9259be2ed59e436c75b76d3ca918330c3c91ddb1e8358ff3bc1a76c2e7bda04"}, 2030 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2193854657219a10f5967b8f1dc4ae3139522e48b2f0ca4235a57957cb287e00"}, 2031 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:109bd194283a77983c817d121e1b47b1fea5a2122267e00ec62e902227f388ce"}, 2032 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7fa34ba6bc3a69d08ca3964a8223a48a0ac60ae6961a0e5854e66cfa5eb28d57"}, 2033 | {file = "pyobjc_framework_CoreAudio-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7733d9be922f3de5801143247ed25cbd443dcf04717e9d2fc94e40b8be24e569"}, 2034 | ] 2035 | pyobjc-framework-coreaudiokit = [ 2036 | {file = "pyobjc-framework-CoreAudioKit-6.2.2.tar.gz", hash = "sha256:5df22ce5dab4c02676825c4c30024d693efc81e04d822c5bf4e02d6baea75dd7"}, 2037 | {file = "pyobjc_framework_CoreAudioKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6ad19c1194b4bbbc35118420400822e0640450ca02289f41f839020581d1da02"}, 2038 | ] 2039 | pyobjc-framework-corebluetooth = [ 2040 | {file = "pyobjc-framework-CoreBluetooth-6.2.2.tar.gz", hash = "sha256:4454375b76ec1487dcc24f09ee8a2db8c284de548ce67c41bd489e93093e4896"}, 2041 | {file = "pyobjc_framework_CoreBluetooth-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b6be6eac503ceeae04027824773f2ca317dc824a8ac89b8908412624cc6a83c8"}, 2042 | ] 2043 | pyobjc-framework-coredata = [ 2044 | {file = "pyobjc-framework-CoreData-6.2.2.tar.gz", hash = "sha256:ae89b11608ffa13d2b8475274c63ab7d22e856978dd3a70a5c21893085c6fdcb"}, 2045 | {file = "pyobjc_framework_CoreData-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e71a881d7f51165d96527a28f6a597fe63e87036efcc08f73fc993cb0785c77"}, 2046 | ] 2047 | pyobjc-framework-corehaptics = [ 2048 | {file = "pyobjc-framework-CoreHaptics-6.2.2.tar.gz", hash = "sha256:21f9a9ea2295258220056f9152e8fd996ac8b2f33b110b662ab525304ede95c5"}, 2049 | {file = "pyobjc_framework_CoreHaptics-6.2.2-py2.py3-none-any.whl", hash = "sha256:209767b1a4daba13bb13cdc6bf8fbd75f5de422105217461662fd79fc3496838"}, 2050 | ] 2051 | pyobjc-framework-corelocation = [ 2052 | {file = "pyobjc-framework-CoreLocation-6.2.2.tar.gz", hash = "sha256:237722c1a9d90ce1fc0cc7b988375a816e9489bec2e0ddc6c83205ed1e7eb8bf"}, 2053 | {file = "pyobjc_framework_CoreLocation-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fe5900e5d3d7cb9e7652fc9389d92edf71da2f57b305edf9dc0642bcdfaf56da"}, 2054 | ] 2055 | pyobjc-framework-coremedia = [ 2056 | {file = "pyobjc-framework-CoreMedia-6.2.2.tar.gz", hash = "sha256:962d0bb705a7c3934a37e5e128c82e153fe9261246897d366bc5b5c6f3de2a69"}, 2057 | {file = "pyobjc_framework_CoreMedia-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cece414593e301cd3c24959bc2ff375d0891a6c051b2bc0d0fbf1c53bc637a08"}, 2058 | ] 2059 | pyobjc-framework-coremediaio = [ 2060 | {file = "pyobjc-framework-CoreMediaIO-6.2.2.tar.gz", hash = "sha256:2e656a6d101e7ee3fa213636c879e22f78230631b800029d243f1ba04cdef9df"}, 2061 | {file = "pyobjc_framework_CoreMediaIO-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:49e4cd70d295895da0032594d5f40d0be6c19a3d749c6a9fb27ad8225a1a1463"}, 2062 | ] 2063 | pyobjc-framework-coreml = [ 2064 | {file = "pyobjc-framework-CoreML-6.2.2.tar.gz", hash = "sha256:c7d11d7b590556a811c6139d603f2cb0c17e3bf92b5f1d01b711b10f87fc8ada"}, 2065 | {file = "pyobjc_framework_CoreML-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ca87242e73a4d0a9ab8db210893dda08402e44bcdd917d209a707346c579e15c"}, 2066 | ] 2067 | pyobjc-framework-coremotion = [ 2068 | {file = "pyobjc-framework-CoreMotion-6.2.2.tar.gz", hash = "sha256:121612fc4d6aa0b13af8dcf3623175e543c38960f916ad06739fefad9f1c71e3"}, 2069 | {file = "pyobjc_framework_CoreMotion-6.2.2-py2.py3-none-any.whl", hash = "sha256:2a32cc8a7a5aa3a6fb4f6f3a44fb82fa69755bba6d1d24a4b7269ef102669be5"}, 2070 | ] 2071 | pyobjc-framework-coreservices = [ 2072 | {file = "pyobjc-framework-CoreServices-6.2.2.tar.gz", hash = "sha256:00c3106fa9541385a280856a07ec13498efb9f22a7d58979753c98f993e15ae8"}, 2073 | {file = "pyobjc_framework_CoreServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d00e5fe9759a312f7a508771ee8dbb57433c9519e8675c77a07b18bad59820b9"}, 2074 | ] 2075 | pyobjc-framework-corespotlight = [ 2076 | {file = "pyobjc-framework-CoreSpotlight-6.2.2.tar.gz", hash = "sha256:bb8f21db764a141ed97423869883700ab567253c73158f002548eec9a1e2a151"}, 2077 | {file = "pyobjc_framework_CoreSpotlight-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:26123a2cf9bc3b627346a7a58c2ce257e4b4f7baa5aead7df8b43ab402e2379b"}, 2078 | ] 2079 | pyobjc-framework-coretext = [ 2080 | {file = "pyobjc-framework-CoreText-6.2.2.tar.gz", hash = "sha256:944fda1bd9c2827e36907216a930fcaf429788132616bed3d687ba0e80405d34"}, 2081 | {file = "pyobjc_framework_CoreText-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0a5f2288b1e29d93d00d708d0e10d8ca49af1116772d48d0623cc62ffad12918"}, 2082 | ] 2083 | pyobjc-framework-corewlan = [ 2084 | {file = "pyobjc-framework-CoreWLAN-6.2.2.tar.gz", hash = "sha256:49d14a82541f0ddbf5ecfd7d1fec9a2103e4a76964e0840f21257c7043a6c4d5"}, 2085 | {file = "pyobjc_framework_CoreWLAN-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:10a6d761c90fee293b5638375a095214673b5d14fca9d494f287ea9d0168148d"}, 2086 | ] 2087 | pyobjc-framework-cryptotokenkit = [ 2088 | {file = "pyobjc-framework-CryptoTokenKit-6.2.2.tar.gz", hash = "sha256:a7ee19dfae514ff6871648cb182b33d50fb2a19a44475e7e9c93cab7078a76d7"}, 2089 | {file = "pyobjc_framework_CryptoTokenKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a71a366a38255ed3867119c37c7c853000e8dc4839f74186a7c2930952b63d17"}, 2090 | ] 2091 | pyobjc-framework-devicecheck = [ 2092 | {file = "pyobjc-framework-DeviceCheck-6.2.2.tar.gz", hash = "sha256:eec96526096f4b5d6f447bac4d88587a8b1d0281e8378665c08a55d0a28ae7b8"}, 2093 | {file = "pyobjc_framework_DeviceCheck-6.2.2-py2.py3-none-any.whl", hash = "sha256:e4ef8cd4f30f0149e53efb6ee0a0324b6db9ec35530893182facfa496ed60fa9"}, 2094 | ] 2095 | pyobjc-framework-dictionaryservices = [ 2096 | {file = "pyobjc-framework-DictionaryServices-6.2.2.tar.gz", hash = "sha256:be01129d642ac516622c1f4998fec37a7969b992271757aadaeeef2b3d601bdc"}, 2097 | {file = "pyobjc_framework_DictionaryServices-6.2.2-py2.py3-none-any.whl", hash = "sha256:a99797dfa22687e27a41fda42def812bb4f45ed99c5d4a254a54338ee15b77e6"}, 2098 | ] 2099 | pyobjc-framework-discrecording = [ 2100 | {file = "pyobjc-framework-DiscRecording-6.2.2.tar.gz", hash = "sha256:445a18666d126da878d456558a43dd43990dcee9516cddb9807a37d60a6327d8"}, 2101 | {file = "pyobjc_framework_DiscRecording-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:dd0b9b2d58de77caa700396d73a9358fea7de2c2fe1c9e061f20b3f0833b4cac"}, 2102 | ] 2103 | pyobjc-framework-discrecordingui = [ 2104 | {file = "pyobjc-framework-DiscRecordingUI-6.2.2.tar.gz", hash = "sha256:569a462566538c737c57c41987e8bafd07fa4cd91eb668b846dd18dbf2aa68fd"}, 2105 | {file = "pyobjc_framework_DiscRecordingUI-6.2.2-py2.py3-none-any.whl", hash = "sha256:b9937c119f0bc021187f0e2c923972feee0a64b7e32d99736c6013e9e0d15043"}, 2106 | ] 2107 | pyobjc-framework-diskarbitration = [ 2108 | {file = "pyobjc-framework-DiskArbitration-6.2.2.tar.gz", hash = "sha256:efcf0e270d4a28f61fc12fa04204d61fb70ff3eaa975606a8e8cf7efba0bcd2c"}, 2109 | {file = "pyobjc_framework_DiskArbitration-6.2.2-py2.py3-none-any.whl", hash = "sha256:18ddc54b99c55f1970f3f50a1a2e3760931ca039350f015ce92e9f2bd256f48f"}, 2110 | ] 2111 | pyobjc-framework-dvdplayback = [ 2112 | {file = "pyobjc-framework-DVDPlayback-6.2.2.tar.gz", hash = "sha256:13d456dddeeec5bee406b701ace1c2f977dded7ea79b65f83d2699a3d2618513"}, 2113 | {file = "pyobjc_framework_DVDPlayback-6.2.2-py2.py3-none-any.whl", hash = "sha256:4daa2fa86842101231adc793a2951badaf068630268be7c1f82b7507fed6eb46"}, 2114 | ] 2115 | pyobjc-framework-eventkit = [ 2116 | {file = "pyobjc-framework-EventKit-6.2.2.tar.gz", hash = "sha256:da75124d740f4f993461773e4f40f7be5f5da544e21dc7b037fa64a5eb2071c2"}, 2117 | {file = "pyobjc_framework_EventKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:10b4c1971dc8d0fcd7dac3f5f2f956fdd102c88dded8f21733c843e6e04798a6"}, 2118 | ] 2119 | pyobjc-framework-exceptionhandling = [ 2120 | {file = "pyobjc-framework-ExceptionHandling-6.2.2.tar.gz", hash = "sha256:e65a43a809f792fd27280fb6dcc8e11726571aa3bfd9650aedd0f17f229383f4"}, 2121 | {file = "pyobjc_framework_ExceptionHandling-6.2.2-py2.py3-none-any.whl", hash = "sha256:9e2c345a5de0b6451d4e8b257be798f7cc555c15c29c3dcdef1131127e7e9f73"}, 2122 | ] 2123 | pyobjc-framework-executionpolicy = [ 2124 | {file = "pyobjc-framework-ExecutionPolicy-6.2.2.tar.gz", hash = "sha256:7dc7565531140a408dd26fabb3274176e0e7f7f718f4fe6518e5b64f0988213b"}, 2125 | {file = "pyobjc_framework_ExecutionPolicy-6.2.2-py2.py3-none-any.whl", hash = "sha256:5f6278f196b53834c04e74a7c36c50f94e7cd8964bfa2dcd8db2eef534e72c77"}, 2126 | ] 2127 | pyobjc-framework-externalaccessory = [ 2128 | {file = "pyobjc-framework-ExternalAccessory-6.2.2.tar.gz", hash = "sha256:7a1e93f54c40b6d277c8b0579b497ae4b42e0704388ccf4bd44b7caee0d63fec"}, 2129 | {file = "pyobjc_framework_ExternalAccessory-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7e716b7be0d86e0a3892646f74b3fe7a06c4584839fbd6e07784ac95ab5b68b3"}, 2130 | ] 2131 | pyobjc-framework-fileprovider = [ 2132 | {file = "pyobjc-framework-FileProvider-6.2.2.tar.gz", hash = "sha256:1502e27999dcc489502a02ca2bf8620c9e93e7f65007041605ce5da12d777be8"}, 2133 | {file = "pyobjc_framework_FileProvider-6.2.2-py2.py3-none-any.whl", hash = "sha256:619a12a186e2ac5264bf2b6ebbbcdee6d355a1c60521a40b1db90b0a892808b5"}, 2134 | ] 2135 | pyobjc-framework-fileproviderui = [ 2136 | {file = "pyobjc-framework-FileProviderUI-6.2.2.tar.gz", hash = "sha256:1b22dc8a1dad2e8569aa46f4e978c05028425528ba466a6b3cb47115a68492b6"}, 2137 | {file = "pyobjc_framework_FileProviderUI-6.2.2-py2.py3-none-any.whl", hash = "sha256:efec0801d67a006feb404a60ab3966bbc6e933856f368b3565304a44e9ab0299"}, 2138 | ] 2139 | pyobjc-framework-findersync = [ 2140 | {file = "pyobjc-framework-FinderSync-6.2.2.tar.gz", hash = "sha256:3a31aec9bfcb97374550a8689b6379983aa21753a07f9d9d9fae8083b205d629"}, 2141 | {file = "pyobjc_framework_FinderSync-6.2.2-py2.py3-none-any.whl", hash = "sha256:5b72a80e4a262cb0525dc9e96d2791d86343c37c8a76583afe5141c3a6c0b153"}, 2142 | ] 2143 | pyobjc-framework-fsevents = [ 2144 | {file = "pyobjc-framework-FSEvents-6.2.2.tar.gz", hash = "sha256:8e2cdfb48e1bca53dc67fc4b219a891ec6c07b2a422f7e3da0ce4ccff258f2b7"}, 2145 | {file = "pyobjc_framework_FSEvents-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d92526e5f0a1763088dd609072b7337a9e58ea698697a1500ad95409c32b64ce"}, 2146 | ] 2147 | pyobjc-framework-gamecenter = [ 2148 | {file = "pyobjc-framework-GameCenter-6.2.2.tar.gz", hash = "sha256:d961ac6ea9a39f55d8e5b3726794adc0fc88df4117631509a1372ffb2dad5a5c"}, 2149 | {file = "pyobjc_framework_GameCenter-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f9cffd8d1c88d890c7e9a359d4d37eccbad384096cd223811cf9c23fa283e168"}, 2150 | ] 2151 | pyobjc-framework-gamecontroller = [ 2152 | {file = "pyobjc-framework-GameController-6.2.2.tar.gz", hash = "sha256:6d96356e00c63437871cec3d881b849a2d635ef29a240bfa07ee74fbe5ce048e"}, 2153 | {file = "pyobjc_framework_GameController-6.2.2-py2.py3-none-any.whl", hash = "sha256:368f1ffad8aefe6378477157e941a853053a380984e1854206f3dbefc86dafb6"}, 2154 | ] 2155 | pyobjc-framework-gamekit = [ 2156 | {file = "pyobjc-framework-GameKit-6.2.2.tar.gz", hash = "sha256:1d9c8d54a5b803076cf39140db5626e7d1a3233c8f45e5c222e455bae857dd93"}, 2157 | {file = "pyobjc_framework_GameKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:610166712a08ebd25c0a990ed2c2a8288db5f7d25ead352488ae2dfbe6b169ee"}, 2158 | ] 2159 | pyobjc-framework-gameplaykit = [ 2160 | {file = "pyobjc-framework-GameplayKit-6.2.2.tar.gz", hash = "sha256:b7b4752090d7fbbb92af8123d65fc7a1c3a751f048bdff0109e418654d4edfa5"}, 2161 | {file = "pyobjc_framework_GameplayKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6229038def1269260da5a3743151366bebef20d0c0369a2c9f8fd811f1f1906e"}, 2162 | ] 2163 | pyobjc-framework-imagecapturecore = [ 2164 | {file = "pyobjc-framework-ImageCaptureCore-6.2.2.tar.gz", hash = "sha256:7540191fb1941452ce17502fcc83896437150c3c084e26c346c00a34360cc2f8"}, 2165 | {file = "pyobjc_framework_ImageCaptureCore-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1789726d4421dfac49920a2a385c31a756dfcc009baf3b123265a0582a85f5f1"}, 2166 | ] 2167 | pyobjc-framework-imserviceplugin = [ 2168 | {file = "pyobjc-framework-IMServicePlugIn-6.2.2.tar.gz", hash = "sha256:756afb6d6c5f6adaf86f3c61268fd506adf16698cd0800cc708c859130ca43ca"}, 2169 | {file = "pyobjc_framework_IMServicePlugIn-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e70ae537c5f628a3be96b6112ceaeb44744d8cea8c761c0c86cdc848db3503a4"}, 2170 | ] 2171 | pyobjc-framework-inputmethodkit = [ 2172 | {file = "pyobjc-framework-InputMethodKit-6.2.2.tar.gz", hash = "sha256:5de9d3fd0a260d53a567294d0713adec7c0d32dc6db0c7b32606932e3398eb60"}, 2173 | {file = "pyobjc_framework_InputMethodKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b0167d9b0cdca5b329dd5fd50c5a797e5f073a3b23b09201e91ae82a0a646696"}, 2174 | ] 2175 | pyobjc-framework-installerplugins = [ 2176 | {file = "pyobjc-framework-InstallerPlugins-6.2.2.tar.gz", hash = "sha256:309c21c10d9a61206cc71238cf4d44a382362688a8983a390020903b649b55c9"}, 2177 | {file = "pyobjc_framework_InstallerPlugins-6.2.2-py2.py3-none-any.whl", hash = "sha256:38a509c661e2b592b75870ac3da746208505898b6faa0a8c338d1512aa309b40"}, 2178 | ] 2179 | pyobjc-framework-instantmessage = [ 2180 | {file = "pyobjc-framework-InstantMessage-6.2.2.tar.gz", hash = "sha256:c1043d4c9ab1aaf53941ec9a6e05d6c2dd46fdc2a5aeb79f8f40097616aefb99"}, 2181 | {file = "pyobjc_framework_InstantMessage-6.2.2-py2.py3-none-any.whl", hash = "sha256:41d933dcbd0fe758f12a4bc384b16fc0718e2f1c45043fe4c5f0c971c20433cc"}, 2182 | ] 2183 | pyobjc-framework-intents = [ 2184 | {file = "pyobjc-framework-Intents-6.2.2.tar.gz", hash = "sha256:fa85f74e13b350d1331ed65548edfa9271308b90decac6c440a7d34cafff5057"}, 2185 | {file = "pyobjc_framework_Intents-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c272fe36404b18199b08bced8acb2f63b0f1b61f35a0b8fa37a6cd46f2b1a1c4"}, 2186 | ] 2187 | pyobjc-framework-interfacebuilderkit = [ 2188 | {file = "pyobjc-framework-InterfaceBuilderKit-6.2.2.tar.gz", hash = "sha256:5a600137127aad32f73d5a4f98e9356a5d782e01fdbd7deba8cef1f44db1a748"}, 2189 | {file = "pyobjc_framework_InterfaceBuilderKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:9e6813d4be3d7defb1ec962906042e31a961d7299bd0d4f14a488392acbc5b3b"}, 2190 | ] 2191 | pyobjc-framework-iosurface = [ 2192 | {file = "pyobjc-framework-IOSurface-6.2.2.tar.gz", hash = "sha256:e97af910e2dc6fb7918f503c03b6f66cb99f477d968502dd9c96b4fdb86cba92"}, 2193 | {file = "pyobjc_framework_IOSurface-6.2.2-py2.py3-none-any.whl", hash = "sha256:04be56c8be967dcbce31d0d5babec19107536db566590962b228894a620eefff"}, 2194 | ] 2195 | pyobjc-framework-ituneslibrary = [ 2196 | {file = "pyobjc-framework-iTunesLibrary-6.2.2.tar.gz", hash = "sha256:3e5f6f6013cd333954fc3439a044181b7179b379a2868103ed067e3f964bafb2"}, 2197 | {file = "pyobjc_framework_iTunesLibrary-6.2.2-py2.py3-none-any.whl", hash = "sha256:61038c8c65ba9d804ad831c64e0874095e0557a2826bfec920e5153f869197fc"}, 2198 | ] 2199 | pyobjc-framework-latentsemanticmapping = [ 2200 | {file = "pyobjc-framework-LatentSemanticMapping-6.2.2.tar.gz", hash = "sha256:48d20ca24540c1385d64a898a4aa87be398e707232a9ea01a3432a4a78ebcf5e"}, 2201 | {file = "pyobjc_framework_LatentSemanticMapping-6.2.2-py2.py3-none-any.whl", hash = "sha256:5f6ce54438f755e87c7dbc6a7baf1c92cef7d09c994873793bd0caf1973f5823"}, 2202 | ] 2203 | pyobjc-framework-launchservices = [ 2204 | {file = "pyobjc-framework-LaunchServices-6.2.2.tar.gz", hash = "sha256:d9c2ae16a113adaa5b8a86481402a6dceb381c1419d33bf5b98fa615975beda2"}, 2205 | {file = "pyobjc_framework_LaunchServices-6.2.2-py2.py3-none-any.whl", hash = "sha256:edc09a001f343b459c130a8518e18b9b7b5006428e152d4dc711e52d5ad76b12"}, 2206 | ] 2207 | pyobjc-framework-libdispatch = [ 2208 | {file = "pyobjc-framework-libdispatch-6.2.2.tar.gz", hash = "sha256:a69aa6d4b6d396c9006ee9b10b2cfb678005ba4f68e3306e58bb7f92b39d3a24"}, 2209 | {file = "pyobjc_framework_libdispatch-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d8c2d74565e0a0fdf68bfeb2a26bccbbcf326f7dbb165fec4d429501959e81ff"}, 2210 | {file = "pyobjc_framework_libdispatch-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aa2543dcab0d5694381619852bfad78d83e3673054c4e72134f7cf15c1c2ad7b"}, 2211 | {file = "pyobjc_framework_libdispatch-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a1430080682893dd39a4ba415f4ab889a3d2c3f50156476052de872bc26bc711"}, 2212 | {file = "pyobjc_framework_libdispatch-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e30681fd6a20c53f569e454e80a4ecb58aeca1ee79e42733c3901917fcd8627"}, 2213 | ] 2214 | pyobjc-framework-linkpresentation = [ 2215 | {file = "pyobjc-framework-LinkPresentation-6.2.2.tar.gz", hash = "sha256:3f01e167aebc07a1db3d2d4fbb5dfaf70d8e5f07596148027243101c1d049835"}, 2216 | {file = "pyobjc_framework_LinkPresentation-6.2.2-py2.py3-none-any.whl", hash = "sha256:f941a701b38f248a8aea281eb1dde8a23891824da563e9ed1a88a56c1f5b0489"}, 2217 | ] 2218 | pyobjc-framework-localauthentication = [ 2219 | {file = "pyobjc-framework-LocalAuthentication-6.2.2.tar.gz", hash = "sha256:8f4ab9fe232ad583061ed161568253445aab55c41df293bfbe1605cabe80818d"}, 2220 | {file = "pyobjc_framework_LocalAuthentication-6.2.2-py2.py3-none-any.whl", hash = "sha256:d547c15770d5c5774815beae4b8a2c133a453cd2d7cb0eea21d2abf44e39a055"}, 2221 | ] 2222 | pyobjc-framework-mapkit = [ 2223 | {file = "pyobjc-framework-MapKit-6.2.2.tar.gz", hash = "sha256:2b7ceaf77c9b9126ac71b2d7549e997047d34375e48ca91a3099ae32e1d342f7"}, 2224 | {file = "pyobjc_framework_MapKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0968591c62439aaa01a88d0fdef906313338c103264b63c21f5a66b5fb6e8f4f"}, 2225 | ] 2226 | pyobjc-framework-mediaaccessibility = [ 2227 | {file = "pyobjc-framework-MediaAccessibility-6.2.2.tar.gz", hash = "sha256:893245c1731aa4a5b8568adb78025bed3c5c1e314e27f663a6f35db23175d0df"}, 2228 | {file = "pyobjc_framework_MediaAccessibility-6.2.2-py2.py3-none-any.whl", hash = "sha256:2c2b3feabe241bf93811a0bd586af6120e92705201a54ab2868e66d6725093ea"}, 2229 | ] 2230 | pyobjc-framework-medialibrary = [ 2231 | {file = "pyobjc-framework-MediaLibrary-6.2.2.tar.gz", hash = "sha256:6c2e76290903ae25dc591e86a489283f79ae1aad67de8b31c88ca3ede3de27dc"}, 2232 | {file = "pyobjc_framework_MediaLibrary-6.2.2-py2.py3-none-any.whl", hash = "sha256:d312618aa9bec856f9c22d1f95330f1c63212e342235f4c7be673fcac9f747c6"}, 2233 | ] 2234 | pyobjc-framework-mediaplayer = [ 2235 | {file = "pyobjc-framework-MediaPlayer-6.2.2.tar.gz", hash = "sha256:8b2e8d432a71c9f265d1db69ebe22b98a34f93543083369f07d694f3a6a3d6f4"}, 2236 | {file = "pyobjc_framework_MediaPlayer-6.2.2-py2.py3-none-any.whl", hash = "sha256:fc9272dbb6fecf82165ae99aec2a9105478316a475b88b120ecb86e74e5465d0"}, 2237 | ] 2238 | pyobjc-framework-mediatoolbox = [ 2239 | {file = "pyobjc-framework-MediaToolbox-6.2.2.tar.gz", hash = "sha256:742140302bf848fb25971fe0922269088ca498346d1fa5d078260aa976cb63c5"}, 2240 | {file = "pyobjc_framework_MediaToolbox-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1160fe5fe0425ae7d0adb462d260700bf26e15b54ef268868b0017f2ff24e4b9"}, 2241 | ] 2242 | pyobjc-framework-message = [ 2243 | {file = "pyobjc-framework-Message-6.2.2.tar.gz", hash = "sha256:8128d1bec5204e808fbb867f6a96fe3a26b94b93613bbe5f9d2dc0c0d994a33b"}, 2244 | {file = "pyobjc_framework_Message-6.2.2-py2.py3-none-any.whl", hash = "sha256:ebe14dfabd34f8af8f255bff110113fdbbf33c2aaf384264f00cbbadcddb9137"}, 2245 | ] 2246 | pyobjc-framework-metal = [ 2247 | {file = "pyobjc-framework-Metal-6.2.2.tar.gz", hash = "sha256:ca916bc103aeec79507c4d79ce35e853f109e0581965293eaedb9e517d8db2e8"}, 2248 | {file = "pyobjc_framework_Metal-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:77dd2c2c0a7e3cc04121c07af8bbe48daadd22b5517e3a70ad619fcc9b1ea66a"}, 2249 | ] 2250 | pyobjc-framework-metalkit = [ 2251 | {file = "pyobjc-framework-MetalKit-6.2.2.tar.gz", hash = "sha256:825fc2e49f61df8ddf9ac74035c0aae696eaa9b8f797a107ba8bdd824f0312aa"}, 2252 | {file = "pyobjc_framework_MetalKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:02aa2ac1c2b0efcbe361c4796a3c1083029726faa7a0b2ac1412fb86bf033c98"}, 2253 | ] 2254 | pyobjc-framework-modelio = [ 2255 | {file = "pyobjc-framework-ModelIO-6.2.2.tar.gz", hash = "sha256:fae52369376bfe9d197abc36bdd84d934aec058cdd0a1afa9cad533d975f70cb"}, 2256 | {file = "pyobjc_framework_ModelIO-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:171f8803e39cd6cb9262347931077c8eecb583cbfaecaf5c9fec17d877f8654b"}, 2257 | ] 2258 | pyobjc-framework-multipeerconnectivity = [ 2259 | {file = "pyobjc-framework-MultipeerConnectivity-6.2.2.tar.gz", hash = "sha256:8545d8210e645aa9752d07eafdea006972e9efc3575083368768f8ac872711cc"}, 2260 | {file = "pyobjc_framework_MultipeerConnectivity-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a9672361448d42d16b12763e573c8d768e7de1b10e4a9dbaa521ab1527dd03ba"}, 2261 | ] 2262 | pyobjc-framework-naturallanguage = [ 2263 | {file = "pyobjc-framework-NaturalLanguage-6.2.2.tar.gz", hash = "sha256:45ffea5d3b8ff9c85c4bf3e6de1714daae675ac3fd1abd957a0e57af8f90a260"}, 2264 | {file = "pyobjc_framework_NaturalLanguage-6.2.2-py2.py3-none-any.whl", hash = "sha256:056326f51e242aaf33978bf09974b8cca1dc13903b944a28c4481317626038a9"}, 2265 | ] 2266 | pyobjc-framework-netfs = [ 2267 | {file = "pyobjc-framework-NetFS-6.2.2.tar.gz", hash = "sha256:7f385f9d7ecab82800ccda7c6684e9c4e1cf932f78c0c75f5daa1ec469a51086"}, 2268 | {file = "pyobjc_framework_NetFS-6.2.2-py2.py3-none-any.whl", hash = "sha256:9934f64fcb06fb372166f1f08f5b84ef363dfd98467e6f4b32569d65fefb9ed5"}, 2269 | ] 2270 | pyobjc-framework-network = [ 2271 | {file = "pyobjc-framework-Network-6.2.2.tar.gz", hash = "sha256:91eed661d55293ed935a24c83a1745fa966b443d280ad85b41ec7046621917b6"}, 2272 | {file = "pyobjc_framework_Network-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:89de1d32f0435b69d6183fc2991b543f8a894f46ad22391c42cfa5a45794c330"}, 2273 | ] 2274 | pyobjc-framework-networkextension = [ 2275 | {file = "pyobjc-framework-NetworkExtension-6.2.2.tar.gz", hash = "sha256:1d413d445e6736c5594615260816d1ebbf04e5d202c988be3042f842e172f76e"}, 2276 | {file = "pyobjc_framework_NetworkExtension-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ef6c7dda2efdf61ec32fb4c79b017996d37fa5f274b06e9cfb950ef62c10f197"}, 2277 | ] 2278 | pyobjc-framework-notificationcenter = [ 2279 | {file = "pyobjc-framework-NotificationCenter-6.2.2.tar.gz", hash = "sha256:79241e13b692f126544e149c3316ac766092e573e47f62f80b28a6c1060a05a1"}, 2280 | {file = "pyobjc_framework_NotificationCenter-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:dd1d8a9a81d4ac29f1f0c12ba46884536622ed89b2e22bff8b82d1a4080cf17e"}, 2281 | ] 2282 | pyobjc-framework-opendirectory = [ 2283 | {file = "pyobjc-framework-OpenDirectory-6.2.2.tar.gz", hash = "sha256:c78b403848be3f72528845818d767e29db425f391602f41c76a873fb9a133d50"}, 2284 | {file = "pyobjc_framework_OpenDirectory-6.2.2-py2.py3-none-any.whl", hash = "sha256:dce16813f5b72fd6fb536c289ae6d6e618843af9ed44dba57c5d6f7bbabd8e09"}, 2285 | ] 2286 | pyobjc-framework-osakit = [ 2287 | {file = "pyobjc-framework-OSAKit-6.2.2.tar.gz", hash = "sha256:8a7432023304d7b6b5b130182e29d9b67294ec73d2b0572966186db6bee9f61b"}, 2288 | {file = "pyobjc_framework_OSAKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:4ec4f0589fa863a0b0c242f5bc4f13e306d1b0412bd650bba4b36e924c1c87c3"}, 2289 | ] 2290 | pyobjc-framework-oslog = [ 2291 | {file = "pyobjc-framework-OSLog-6.2.2.tar.gz", hash = "sha256:574b05bdfb6913c0089c937af9f1fd8a88810701ed86e7bca4385376f47fe487"}, 2292 | {file = "pyobjc_framework_OSLog-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:087839d1db5df76a922b054ea67262f4b9a132935129619d44e938426fa8081f"}, 2293 | ] 2294 | pyobjc-framework-pencilkit = [ 2295 | {file = "pyobjc-framework-PencilKit-6.2.2.tar.gz", hash = "sha256:2edb6e88f9d0093cf20a6b20bd8b646d918d246f1a9b523d176ba360c47f6e91"}, 2296 | {file = "pyobjc_framework_PencilKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:305fa33989294c97e0ec70ac9c9782883f40fbe3c45452a8f9fdd04e743b100f"}, 2297 | ] 2298 | pyobjc-framework-photos = [ 2299 | {file = "pyobjc-framework-Photos-6.2.2.tar.gz", hash = "sha256:6dd3598f9f3428641d8f95c5d64b87a5d83ee95a7cb5937284514626042cf275"}, 2300 | {file = "pyobjc_framework_Photos-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ffff560b7eb4f5abdacbae1d7568c02abd9cd63c30591b5328887d3b01572c39"}, 2301 | ] 2302 | pyobjc-framework-photosui = [ 2303 | {file = "pyobjc-framework-PhotosUI-6.2.2.tar.gz", hash = "sha256:6129cd970cba8f37dd8ee1c57484b7263470b7faf0a20341e5bb99b0ecf911f2"}, 2304 | {file = "pyobjc_framework_PhotosUI-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65f975301c3d9b193e56c0a60a1e0ecfd38a376f6b72abfd31a05a905f5e389c"}, 2305 | ] 2306 | pyobjc-framework-preferencepanes = [ 2307 | {file = "pyobjc-framework-PreferencePanes-6.2.2.tar.gz", hash = "sha256:8bda7a9cb9cd2844dedc79869fd7cd9275b7bf9c4845cf6ab6d64205172b4376"}, 2308 | {file = "pyobjc_framework_PreferencePanes-6.2.2-py2.py3-none-any.whl", hash = "sha256:5e6cf700e0315c9ae75b56c4c528af6607044f147f2dcd58e0af7954955b2eaa"}, 2309 | ] 2310 | pyobjc-framework-pubsub = [ 2311 | {file = "pyobjc-framework-PubSub-6.2.2.tar.gz", hash = "sha256:519f6402a10f666f624cdcbbed35ec3919da5d0be77fb56d92e1b5be12f35ef1"}, 2312 | {file = "pyobjc_framework_PubSub-6.2.2-py2.py3-none-any.whl", hash = "sha256:5307d630572905cbfeecf120875104d21f714cd32d7ce24c209edd1a72c0ffa6"}, 2313 | ] 2314 | pyobjc-framework-pushkit = [ 2315 | {file = "pyobjc-framework-PushKit-6.2.2.tar.gz", hash = "sha256:6454d70fb0140b7943027ae9e33f1bfd0a6dbd6c6a24b37e0e4a3f6a884c3c82"}, 2316 | {file = "pyobjc_framework_PushKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0018f99f713f1b2387db21f9a25e129bf90e9d2e55dd613051d2066fdb15226c"}, 2317 | ] 2318 | pyobjc-framework-qtkit = [ 2319 | {file = "pyobjc-framework-QTKit-6.2.2.tar.gz", hash = "sha256:fa750f227d6f32a5314d80b261fe77fa085ada31cf8865e4bfbbe828d22f84a2"}, 2320 | {file = "pyobjc_framework_QTKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ce01d41a21e4d6feaa2c00c6f022660aad5548bcf78bc3414e426e9f93eabef2"}, 2321 | ] 2322 | pyobjc-framework-quartz = [ 2323 | {file = "pyobjc-framework-Quartz-6.2.2.tar.gz", hash = "sha256:5a56cfc0289061eaf33f04e3c73e749e04f177b0c1ee8749aa46e87d1e897cda"}, 2324 | {file = "pyobjc_framework_Quartz-6.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:56d183dc32b11f15ceb0833a2a24953d1212264f07c274e2b8878e691eb72472"}, 2325 | {file = "pyobjc_framework_Quartz-6.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a57c7f50286d96ee7b9051c657a8607f0449949891cf0697be3efac76a97be7e"}, 2326 | {file = "pyobjc_framework_Quartz-6.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:552b15eb409f87d34870345feabe6695375a031d8c4063f175dbaa3422005160"}, 2327 | {file = "pyobjc_framework_Quartz-6.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15f3c7b50d0543f66b927e28cd336c1a6962d58c9808799f49dcf30e4a1a13c2"}, 2328 | ] 2329 | pyobjc-framework-quicklookthumbnailing = [ 2330 | {file = "pyobjc-framework-QuickLookThumbnailing-6.2.2.tar.gz", hash = "sha256:2a34eb83813a2aa5fbe072cbe03d5557b8e80449fbc788e7008994b22417d580"}, 2331 | {file = "pyobjc_framework_QuickLookThumbnailing-6.2.2-py2.py3-none-any.whl", hash = "sha256:fb66393583f4e3a3a7b56d0d209d5dd590f59c3133d5ccd5a9fced3b314e9d44"}, 2332 | ] 2333 | pyobjc-framework-safariservices = [ 2334 | {file = "pyobjc-framework-SafariServices-6.2.2.tar.gz", hash = "sha256:396a7fca2d5ff039a9031b9d1f54080a334e26b2cf10664e5568b49487c32e9a"}, 2335 | {file = "pyobjc_framework_SafariServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9624e27795b28419486a461b2a5f84e100eb4c1ce74fca88d31c4133c77329b9"}, 2336 | ] 2337 | pyobjc-framework-scenekit = [ 2338 | {file = "pyobjc-framework-SceneKit-6.2.2.tar.gz", hash = "sha256:b0a0a5866220aa9972248556f9a09e4f14f316870f9f4e12c3d666594a7cb33b"}, 2339 | {file = "pyobjc_framework_SceneKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:991fa198396af69200dad314258c3f3aeec7028a0a09e50333c0e4d392c0626d"}, 2340 | ] 2341 | pyobjc-framework-screensaver = [ 2342 | {file = "pyobjc-framework-ScreenSaver-6.2.2.tar.gz", hash = "sha256:f0479f1c6ce1bdbc8723a9194b9ee9a3c87ddd82dbc16e59dc1bb9a58326453b"}, 2343 | {file = "pyobjc_framework_ScreenSaver-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:eb057b5c1c6a82c5ba9e7c64c93f07ffed18b8e4432c7c56da4df97940bba5b1"}, 2344 | ] 2345 | pyobjc-framework-scriptingbridge = [ 2346 | {file = "pyobjc-framework-ScriptingBridge-6.2.2.tar.gz", hash = "sha256:f3f659351f6686ebabafce955a2d55e4f32c791c755f27641b37b5cd9974c037"}, 2347 | {file = "pyobjc_framework_ScriptingBridge-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a0e03297e404bbdbcc4a51a1dfa271ce9b9a7dd9a123ae5e9b303668be246e6a"}, 2348 | ] 2349 | pyobjc-framework-searchkit = [ 2350 | {file = "pyobjc-framework-SearchKit-6.2.2.tar.gz", hash = "sha256:2830e820a6edff87712973f015e888188b1a16256e58bec10497725da1a907f3"}, 2351 | {file = "pyobjc_framework_SearchKit-6.2.2-py2.py3-none-any.whl", hash = "sha256:1bb41f5c7c1a0885d7039acc024c4ec94140b639b27f3302ce4c8162f096e3ca"}, 2352 | ] 2353 | pyobjc-framework-security = [ 2354 | {file = "pyobjc-framework-Security-6.2.2.tar.gz", hash = "sha256:c53d9f6d83edeb9a55e793f01a6d1b7d8d1a6a23f023db05cac86cde327f829c"}, 2355 | {file = "pyobjc_framework_Security-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1c38a5df00e1547431ab072ba0e4e942c43da14be505cac9502a8c6fde6671ac"}, 2356 | ] 2357 | pyobjc-framework-securityfoundation = [ 2358 | {file = "pyobjc-framework-SecurityFoundation-6.2.2.tar.gz", hash = "sha256:dd2a8f0ca051d756a8c7a7272de7d44e426ba76a417b947fc49cc3c3c8427aa3"}, 2359 | {file = "pyobjc_framework_SecurityFoundation-6.2.2-py2.py3-none-any.whl", hash = "sha256:b9b01a4228dadf82d86feabcea8c08facaadf59fbe22a0881025db88318916e9"}, 2360 | ] 2361 | pyobjc-framework-securityinterface = [ 2362 | {file = "pyobjc-framework-SecurityInterface-6.2.2.tar.gz", hash = "sha256:f5e379789cedc96908e9be021033d2228dd36c30dc804e59495854e443db8e16"}, 2363 | {file = "pyobjc_framework_SecurityInterface-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3645e11780b45ec819354e593895f7eb7c81ac968fb3e3984dfafe0ea4fbc0bf"}, 2364 | ] 2365 | pyobjc-framework-servernotification = [ 2366 | {file = "pyobjc-framework-ServerNotification-6.2.2.tar.gz", hash = "sha256:e7a745f9d43fed99d1b06b2e06cc0e651aaca74a7905fbe3860f27f6e485801a"}, 2367 | {file = "pyobjc_framework_ServerNotification-6.2.2-py2.py3-none-any.whl", hash = "sha256:9bbbfaaa3023318a11faa0bf246e64bd13c380bb08b31fab61d83487383e17a6"}, 2368 | ] 2369 | pyobjc-framework-servicemanagement = [ 2370 | {file = "pyobjc-framework-ServiceManagement-6.2.2.tar.gz", hash = "sha256:c2483005f132c8ec6912662505d2962d72e37f966388d482a87c1344c25eedd4"}, 2371 | {file = "pyobjc_framework_ServiceManagement-6.2.2-py2.py3-none-any.whl", hash = "sha256:20690aa93a8476d6b6b7693679c8288383cef45c6483a79a0880e69f86acab59"}, 2372 | ] 2373 | pyobjc-framework-social = [ 2374 | {file = "pyobjc-framework-Social-6.2.2.tar.gz", hash = "sha256:95a4e33bbe30c7fa627dc8f5a5b726a8354ea24005ddffacb2d477648b263077"}, 2375 | {file = "pyobjc_framework_Social-6.2.2-py2.py3-none-any.whl", hash = "sha256:7331dd9084728d8b5df53bb38ccc77672e45c52726020e63e7c1c00263a85fcd"}, 2376 | ] 2377 | pyobjc-framework-soundanalysis = [ 2378 | {file = "pyobjc-framework-SoundAnalysis-6.2.2.tar.gz", hash = "sha256:31a3d3e6c12468f5840c7ea66f2b571bd3443634868e57f6038c9e60b07fd43b"}, 2379 | {file = "pyobjc_framework_SoundAnalysis-6.2.2-py2.py3-none-any.whl", hash = "sha256:80edaa071e9d880751bc67293679a235cf6083b713f0a362a29376f42efb5370"}, 2380 | ] 2381 | pyobjc-framework-speech = [ 2382 | {file = "pyobjc-framework-Speech-6.2.2.tar.gz", hash = "sha256:6ff32726896b56dbf26990dbf1cadd64c2066865331ba926ff580a837f9a57d9"}, 2383 | {file = "pyobjc_framework_Speech-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:95b8c6cc380ca33835343ec66b3d97279a03ed1eeb5609f0e5178a53aa61b146"}, 2384 | ] 2385 | pyobjc-framework-spritekit = [ 2386 | {file = "pyobjc-framework-SpriteKit-6.2.2.tar.gz", hash = "sha256:5523cd33bb3b906fbb354a4bfd910629863014004aab0ed1764083fdf5c91eeb"}, 2387 | {file = "pyobjc_framework_SpriteKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c63c700f03cae3861895d9d78fae2bd477d1440f8595ece2dde68b140ac2dc75"}, 2388 | ] 2389 | pyobjc-framework-storekit = [ 2390 | {file = "pyobjc-framework-StoreKit-6.2.2.tar.gz", hash = "sha256:3fdbcd185c4452f102af9e1d9e3d37757f5afcdac6ef315bc0f73f2a9db8146d"}, 2391 | {file = "pyobjc_framework_StoreKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0e64ae84c4b8af354b51a5f784f1e2b4eb2f51ec1a9969775e676543901e81df"}, 2392 | ] 2393 | pyobjc-framework-syncservices = [ 2394 | {file = "pyobjc-framework-SyncServices-6.2.2.tar.gz", hash = "sha256:645490178ee95d9bb554cde8e9180e6c490ed112f3691a3fe258b34a9b5d3deb"}, 2395 | {file = "pyobjc_framework_SyncServices-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc4c00da0cb2f838e798c88208994eee5cdc4fc2ce11fbd72189acff96a89ae6"}, 2396 | ] 2397 | pyobjc-framework-systemconfiguration = [ 2398 | {file = "pyobjc-framework-SystemConfiguration-6.2.2.tar.gz", hash = "sha256:1611f6c561669beff0bad18a9f4fe0724424acc92ed47cc8fc3949532402c95d"}, 2399 | {file = "pyobjc_framework_SystemConfiguration-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cef76b15fe09f3a3457a1de97cdcd619953d22b416f46c74b927909bf988f361"}, 2400 | ] 2401 | pyobjc-framework-systemextensions = [ 2402 | {file = "pyobjc-framework-SystemExtensions-6.2.2.tar.gz", hash = "sha256:386586e9d7d87a9b8ccb267d62fb7f950de063f890c89c7e4728f22289a892fe"}, 2403 | {file = "pyobjc_framework_SystemExtensions-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:35e06352764f5b2c6fc10c589990feb56c6ae0efdc35cf6e9c63a49cba741ff2"}, 2404 | ] 2405 | pyobjc-framework-usernotifications = [ 2406 | {file = "pyobjc-framework-UserNotifications-6.2.2.tar.gz", hash = "sha256:40b0cad22ba3f55ed1d25248abcfcb2f3c15064c3c00027e3dcf8ce7be832b22"}, 2407 | {file = "pyobjc_framework_UserNotifications-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aba54a959e129e186467ea5f55e47484cd7244507a0494d73c28906b3c44fdcd"}, 2408 | ] 2409 | pyobjc-framework-videosubscriberaccount = [ 2410 | {file = "pyobjc-framework-VideoSubscriberAccount-6.2.2.tar.gz", hash = "sha256:2a4d38e6a5b2de5493c5836b24de06a288b7ed1973a36a209553b789d466774a"}, 2411 | {file = "pyobjc_framework_VideoSubscriberAccount-6.2.2-py2.py3-none-any.whl", hash = "sha256:0d73209cca77d5e63f783914942766cac94cf06c59467ad085dc62c3edadbb0d"}, 2412 | ] 2413 | pyobjc-framework-videotoolbox = [ 2414 | {file = "pyobjc-framework-VideoToolbox-6.2.2.tar.gz", hash = "sha256:ae60fcfc3f9e8c2e38882b34c87df71b5585c2a7e37dfbf3a23e32c406f95e86"}, 2415 | {file = "pyobjc_framework_VideoToolbox-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0336cc8bcdff16ab6f537286334339cb390731b3d98aa9810e34727ee2155674"}, 2416 | ] 2417 | pyobjc-framework-vision = [ 2418 | {file = "pyobjc-framework-Vision-6.2.2.tar.gz", hash = "sha256:dc03fea57cc52ba15a2b39be6e834cfd49a6e28daf9b862a578a8002a6fc5207"}, 2419 | {file = "pyobjc_framework_Vision-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b78028ab15c3758af1a2f3f82b69880b7db481a29ab6defe0fcf839f39c83554"}, 2420 | ] 2421 | pyobjc-framework-webkit = [ 2422 | {file = "pyobjc-framework-WebKit-6.2.2.tar.gz", hash = "sha256:87e9409ace6d2e29c776bd76df75fe922a1f2a225eef815640c6047d25da8dab"}, 2423 | {file = "pyobjc_framework_WebKit-6.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b04e08ad08720a87934ba57005fb561d081fbb7f4c12b20e78d0e740e433d06f"}, 2424 | ] 2425 | pyobjc-framework-xgridfoundation = [ 2426 | {file = "pyobjc-framework-XgridFoundation-6.2.2.tar.gz", hash = "sha256:02033b88ed90133f1e17fe3c6c0c305b698ea701e9ed8967bce186e69b1e6c7c"}, 2427 | {file = "pyobjc_framework_XgridFoundation-6.2.2-py2.py3-none-any.whl", hash = "sha256:27f44ff1f2776d4596b5d99076d2458c1576d7cc73b8c1f740eab4f7256836e7"}, 2428 | ] 2429 | pyyaml = [ 2430 | {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, 2431 | {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, 2432 | {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, 2433 | {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, 2434 | {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, 2435 | {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, 2436 | {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, 2437 | {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, 2438 | {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, 2439 | {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, 2440 | {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, 2441 | ] 2442 | six = [ 2443 | {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, 2444 | {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, 2445 | ] 2446 | toml = [ 2447 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 2448 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 2449 | ] 2450 | virtualenv = [ 2451 | {file = "virtualenv-20.1.0-py2.py3-none-any.whl", hash = "sha256:b0011228208944ce71052987437d3843e05690b2f23d1c7da4263fde104c97a2"}, 2452 | {file = "virtualenv-20.1.0.tar.gz", hash = "sha256:b8d6110f493af256a40d65e29846c69340a947669eec8ce784fcf3dd3af28380"}, 2453 | ] 2454 | zipp = [ 2455 | {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, 2456 | {file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"}, 2457 | ] 2458 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "cmus-osx" 3 | version = "3.0.6" 4 | description = "Adds track change notifications, and media key support to cmus." 5 | authors = ["Philip Trauner "] 6 | license = "MIT" 7 | readme = "README.md" 8 | 9 | [tool.poetry.dependencies] 10 | python = "^3.7" 11 | mutagen = "^1.42" 12 | pyobjc = "^6.2" 13 | click = "^7.0" 14 | Pillow = "^8.0" 15 | 16 | [tool.poetry.dev-dependencies] 17 | pre-commit = "^1.18" 18 | 19 | [tool.poetry.scripts] 20 | cmus-osx = "cmus_osx:entrypoint" 21 | 22 | [build-system] 23 | requires = ["poetry>=0.12"] 24 | build-backend = "poetry.masonry.api" 25 | --------------------------------------------------------------------------------